Compare commits

..
Author SHA1 Message Date
github-actions[bot]andgithub-actions[bot] 5866992e7d Version Packages (#3208)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-10-10 15:56:34 +02:00
KenandHalvor Haugan 8ab241a980 [Linting] Comment-cleanup in eslint (#3220)
* memo: Cleanup comments

* memo: Updated eslintRc

* bug: Removed ts from global eslint

* Update .eslintrc.js

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>

* memo: Updated temp comment

* Update .eslintrc.js

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>

---------

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>
2024-10-10 15:48:47 +02:00
KenandHalvor Haugan 363d76b9b2 [Linting] Fixed noUselessTernary and useOptionalChain-rules (#3215)
* memo: Added figma-plugin as ignore

* memo: Removed unused noSelfAssigned

* refactor: Fixed useJsxKeyInIterable

* memo: Removed unused noInnerDeclarations

* memo: Removed unused noUselessTernary

* refactor: Fixed useOptionalChan rule biome

* Update @navikt/aksel-icons/__tests__/validate-svg.test.ts

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>

* feat: Better null-check

---------

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>
2024-10-10 15:06:49 +02:00
Ken 5da970fd62 [Linting] Fixed useLiteralKeys rule from biome (#3219)
* memo: Added figma-plugin as ignore

* memo: Removed unused noSelfAssigned

* refactor: Fixed useJsxKeyInIterable

* memo: Removed unused noInnerDeclarations

* refactor: Fixed useLiteralKeys rule

* bug: Fixed typings for sanity publication action

* bug: Fixed typings for sanity publication action

* bug: Fixed typings for sanity publication action

* bug: added null-check
2024-10-10 14:47:11 +02:00
Ken 296e43cab2 [Linting] Fixed useJsxKeyInIterable ,noSelfAssign and noInnerDeclarations rules from biome (#3214)
* memo: Added figma-plugin as ignore

* memo: Removed unused noSelfAssigned

* refactor: Fixed useJsxKeyInIterable

* memo: Removed unused noInnerDeclarations
2024-10-10 14:33:26 +02:00
Ken 85fec974dc Added autoprefixer to @navikt/ds-css devDependencies (#3213)
* bug: added autoprefixer to ds-css devDeps

* ⬆️ Yarn lock
2024-10-10 13:29:56 +02:00
Vegard HaugstvedtandKen 6ddea4eaf2 Feature/combobox pageup and pagedown (#3158)
* Add support for PageUp and PageDown in Combobox.FilteredOptions

* Remove console.log statements

* Add test for PageDown/PageUp

* Open FilteredOptions when pressing PageDown

* Prevent scrolling from moving the whole page

* Consistently scroll to the active element in useVirtualFocus by using useLayoutEffect

It seems like doing it with the state update sometimes encounters a race condition preventing the scrolling.
This removes the need for a private function handling index update and scrolling, simplifying the code.

* Updated test to fit new options order

* Prevent "Home" and "End" in Combobox from scrolling as well

* Add changeset

* Update @navikt/core/react/src/form/combobox/FilteredOptions/useVirtualFocus.ts

Co-authored-by: Ken <26967723+KenAJoh@users.noreply.github.com>

* useEffect seems to work the same way, and works better for SSR

* Removed code that did nothing

* Added the same check we have for PageDown, etc. Unsure if it is neccessary.

* Change behaviour for "Home" to move focus to the first element instead of Input

* Once we changed virtualFocus.moveFocusToTop to move focus to first element instead of the Input, we now need another function to move it to the Input where applicable.

* Update .changeset/tasty-cats-hear.md

Co-authored-by: Ken <26967723+KenAJoh@users.noreply.github.com>

---------

Co-authored-by: Ken <26967723+KenAJoh@users.noreply.github.com>
2024-10-10 12:05:13 +02:00
Halvor Haugan acea9ebb78 Change "personnummer" to "fødselsnummer" (#3211) 2024-10-10 11:59:28 +02:00
Julian Nymark fdbd634012 Referansesider: dagoversikten BreadCrumbs 2024-10-09 12:37:13 +02:00
Julian Nymark dcf5452d28 Referansesider: dagoversikten content 2024-10-08 16:34:15 +02:00
Sjur 0a8c33bbbe Justerte Danger-farger i LightMode (#3210)
Noen av HEX-verdiene i Danger LightMode er endret.
2024-10-08 15:26:07 +02:00
Vegard Haugstvedt 18b0cf5fa5 Bugfix/combobox disable autocomplete in firefox on android (#3201)
* Disable autocomplete in Combobox to "fix" issue where autocomplete is broken in Firefox on Android

The bug is that after three "correct" characters are entered in a row, the autocomplete inserts the third character incorrectly, messing up the text in the input.
This also happens in other implementations of autocomple, like W3C's ARIA Authoring Practices Guide combobox with inline autocomple.

* Add changeset

* Use type checking instead of useEffect to prevent client code from running server side
2024-10-08 12:37:07 +02:00
Julian Nymark 374a679bc3 Referansesider: ✨ dagoversikten.tsx 2024-10-08 11:53:09 +02:00
github-actions[bot]andgithub-actions[bot] a2e020d4f3 Version Packages (#3206)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-10-08 11:50:48 +02:00
Halvor Haugan 074c8da536 List: ✨ New size 'large' (#3207) 2024-10-08 11:30:47 +02:00
KenandHalvor Haugan bdbd6c24cc [Dependencies] Replaced ts-node with tsx, removed dotenv (#3198)
* refactor: ds-react uses tsx instead of ts-node

* refactor: ds-tailwind uses tsx

* refactor: Website backup and search uses tsx

* refactor: Test urls and rss-feed uses tsx

* refactor: Prop-updates uses tsx

* refactor: All website scripts uses tsx

* refactor: removed dotenv dependency from website

* feat: removed all dependencies to dotenv

* bug: Remove need for env in validate build script

* test: Create empty env file

* test: Scope env-file to build-dir

* bug: Fallback to empty env when no env exsists

* feat: Better error-messaging when fetching new icons

* Update @navikt/aksel-icons/package.json

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>

---------

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>
2024-10-08 10:18:51 +02:00
Ken f0e6c944d8 [Referansesider] Updated contrast tokens to new naming 2024-10-08 10:16:17 +02:00
Ken 22be148832 [Darkside] Moved contrast-tokens to text group
feat: Moved contrast tokens to 'text' collection
feat: Added support for adding custom scopes for each token
2024-10-08 10:06:43 +02:00
KenandHalvor Haugan aac12fe44f [Linting] Fixed useExhaustiveDependencies in biome (#3197)
* feat: Update biome

* feat: migrate biome config

* misc: Ignore semantic-tag rule biome

* refactor: resolved breaking changes after biome update

* feat: remove old excluded biome rule

* feat: Removed a11y/useFocusableInteractive ignore

* refactor: Fix useExhaustiveDependencies  biome

* memo: changeset

* memo: changeset gitmoji

* bug: Re-add selectedOptions to dependency array

* Update @navikt/core/react/src/overlays/dismissablelayer/DismissableLayer.tsx

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>

* bug: Fix initial focus for sidebar icon

* ⚡ remove reduntant memoization of isLimitReached

* bug: re-add sanity-plugin-iframe-pane

---------

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>
2024-10-08 09:05:59 +02:00
Halvor Haugan 324358d086 FileUpload: 💥 Remove UNSAFE-prefix (#3205) 2024-10-07 15:16:25 +02:00
Ken 946cbeb016 [Liniting] Updated to biome v1.9 (#3196)
* feat: Update biome

* feat: migrate biome config

* misc: Ignore semantic-tag rule biome

* refactor: resolved breaking changes after biome update

* feat: remove old excluded biome rule

* feat: Removed a11y/useFocusableInteractive ignore

* refactor: Remove ariaRole rule

* bug: Remove extra fragments in dartepicker stories

* bug: Remove custom image rendering exception for safari on website
2024-10-05 15:41:23 +02:00
Sjur f4d22dae68 Endret Neutral-farger Darth Mode (#3204)
Neutral-fargene ble hentet fra fargene med lavere saturation, som gjorde at de mistet hintet av blått. Endret til den originale skalaen.
2024-10-04 22:09:27 +02:00
Ken ce2f5a9b90 [Darkside] Fixed missing test updates 2024-10-04 16:01:58 +02:00
github-actions[bot]andgithub-actions[bot] cf167064eb Version Packages (#3203)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-10-04 15:25:08 +02:00
Ken 73a6ae1bf1 [Darkside] Fixed no_cache_paths for figma config CDN 2024-10-04 15:24:06 +02:00
Halvor Haugan 95c84e1d01 List: Explicitly set list-style on ol to override reset-CSS (#3202) 2024-10-04 15:14:16 +02:00
Ken 4675857e8f [Darkside] Updated global colors config
feat: Avoid caching config for color-tokens
feat: Remove use of leonardo, hardcode global config
feat: Update 100-400 scale for darkmode
feat: Update 500-1000 scale for global colors
2024-10-04 15:06:32 +02:00
Julian Nymark 2a6e416b5c Referansesider: 🐛 use master branch for GA 2024-10-04 12:50:43 +02:00
Julian Nymark d3c3cafc97 Referansesider: 👷 point to maintained spa-deploy yml (#3199)
* Referansesider: 👷 point to maintained spa-deploy yml

new location: https://github.com/nais/deploy/tree/master/actions/spa-deploy

* Referansesider: 🐛 probably correct yml url (GH action)
2024-10-04 11:47:33 +02:00
KenandHalvor Haugan 678fa6692b [Darkside] Figma plugin for updating variables (#3191)
* feat: Implemented figma plugin

* feat: Can now detect production/development build

* feat: Now supports remote fetch for config

* misc: Stop reset from running by default

* feat:Semantic value handling

* feat: Pre-semantic implementation

* feat: Finished plugin API for semantic variables

* feat: Use this for Figma plugin extension

* bug: Fixed semantic collection naming

* bug: Handle reset correctly

* misc: avoid resetting when updating

* memo: Added comments

* bug: Ignore plugin buildfile from lint

* bug: Fix support for dynamic-page load in figma

* 📝 Better naming, simplified code-def syntax

* feat: Scoped ignorePattern for plugin.js

* memo: better logs for completing update

* Update @navikt/core/tokens/darkside/figma/plugin/AkselVariablesInterface.ts

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>

* Update @navikt/core/tokens/darkside/figma/plugin/AkselVariablesInterface.ts

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>

* memo: Removed extra space for info logging

* refactor: Simplify for-loop for semantic color modes

* refactor: Inline creation of mode, collection and variable

* refactor: readable mapping variables

* feat: Better error-handling if variable is null

* refactor: Remove redundant getModes function

* refactor: Remove redundant getModes function

* refactor: Remove plugin watch function

---------

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>
2024-10-04 11:19:43 +02:00
Ken 87aeb94c64 [Dependencies] Sanity 3.59 update (#3195)
* feat: Updated to sanity 3.59

* bug: Sanity updated icon and media types, so everything broke

* bug: Fallback to default media in article previews if everything is normal
2024-10-03 16:35:00 +02:00
github-actions[bot]andgithub-actions[bot] 4714a5ff32 Version Packages (#3181)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-10-03 16:01:01 +02:00
Halvor HauganandKen ca1d9be88f List: Add indentation and remove aria attributes (#3184)
Co-authored-by: Ken <26967723+KenAJoh@users.noreply.github.com>
2024-10-03 15:06:06 +02:00
Halvor Haugan 2654da8b64 update-article-views: Use latest docker image + remove reduntant stuff in workflow (#3189) 2024-10-03 08:52:48 +02:00
Julian Nymark 8d6418a594 Referansesider: 💄 use correct tokens 2024-10-02 14:24:10 +02:00
Julian Nymark 8269091fb8 Referansesider: 💄 outline offset for focus 2024-10-02 14:15:06 +02:00
Julian Nymark fd82184057 Referansesider: 🎨 aktivitetsplan buttons & select 2024-10-02 14:11:31 +02:00
Julian Nymark 39f2cb8614 Referansesider: 🎨 aktivitetsplan main card 2024-10-02 13:57:07 +02:00
Julian Nymark 4bf298f363 Referansesider: 🎨 Tag to own component, flesh out cards for aktivitetsplan 2024-10-02 12:55:54 +02:00
Halvor HauganandKen 3a239e4e17 [aksel.nav.no] Show breakpoints in GuidePanel examples (#3192)
Co-authored-by: Ken <26967723+KenAJoh@users.noreply.github.com>
2024-10-02 12:23:10 +02:00
Halvor Haugan 4fcfaf3deb [aksel.nav.no] Storybook: Change to Vite framework (#3185) 2024-10-02 10:14:17 +02:00
Julian Nymark 5dbc66daaa Referansesider: 🚧 Aktivitetsplan 2024-10-02 09:53:17 +02:00
Halvor Haugan 555a46b5da Adjust examples of Switch (#3188) 2024-10-01 13:55:03 +02:00
Julian Nymark 73b2bca156 Combobox: 💄 tweak the visibility of chevron (#3187)
* Combobox: 💄 tweak the visibility of chevron

* Combobox: 💄 dim visibility of icons for readonly datepicker, select, and combobox

* Combobox: 💄 dim visibility of icons for readonly datepicker, select, and combobox

* changeset
2024-10-01 13:47:53 +02:00
Julian Nymark 01411dc11f referansesider: 💄 sykepenger++ 2024-10-01 12:02:38 +02:00
Julian Nymark b1b0d23863 Referansesider: 💄 use more tokens 2024-09-30 14:56:17 +02:00
Julian Nymark cf59ce81bf Combobox disabled fixes (#3183)
* Combobox: 💄 remove hover border color when disabled

* Combobox: 💄 remove hover effect on chips when disabled
2024-09-30 13:53:48 +02:00
Julian Nymark 00c0ff31e1 Combobox: 💄 remove hover border color when disabled (#3182) 2024-09-30 13:38:22 +02:00
Julian Nymark d278060e59 Combobox: 🐛 implement Readonly + disabled (#3180)
* 🐛 [Combobox] implement disabled

* 💄 [Combobox] disabled

* ✨ [Combobox] implement readOnly

* 📝 [Combobox] add examples

* 📝 [Combobox] changeset

* 📝 [Combobox] changeset++

* 📝 [Combobox] stories (review fixes)

* 📝 [Combobox] stories (review fixes++)

* Combobox: 🎨 remove ToggleListButton when readonly or disabled

* Combobox: ♿ combobox input does not support native readonly, use nativeReadOnly={false}

* Revert "Combobox: 🎨 remove ToggleListButton when readonly or disabled"

This reverts commit e54a2eca32.

* Combobox: remove unused code
2024-09-30 11:24:47 +02:00
Ken e5d5b67262 [Referansesider] Migrated to new tokens 2024-09-27 14:13:54 +02:00
Ken 246f25cbaa misc: Update darkmode config for tokens 2024-09-27 14:01:51 +02:00
Ken b2a22438ad bug: Fixed CDN-location for figma config 2024-09-27 12:58:30 +02:00
KenandHalvor Haugan 8b8b724e40 [Darkside] Generate Token config to be consumed by Figma plugin (#3172)
* feat: Build figma config

* bug: Fix ignored gitignore config

* refactor: Rename collection -> name key

* feat: pre-update value to figma config

* feat: Re-resolve name with grouping

* feat: Better handling of relative units

* feat: Added better typings, workflow file

* feat: Updated name-parsing for pregen of config

* feat: Removed Unused eslint-disable directive

* feat: Extract figma scope when creating variables

* refactor: Simplified code by extracting logic

* feat: Updated workflow naming

* bug: re-add missing group for semantic color

* feat: Add metadata to figma config

* bug: Added missing 'contrast declaration

* bug: Calculate correct radius values

* refactor: Simplified config structure by unwrapping scopes

* refactor: Extracted logic for group check

* refactor: Only allow string or number as figma value in config

* feat: Added tests for value conversions

* refactor: Renamed figma config file

* update: Lock update

* refactor: Avoid using format as a workaround to extract token list

* Update @navikt/core/tokens/darkside/figma/index.ts

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>

* Update @navikt/core/tokens/darkside/figma/create-tokens.ts

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>

* Update @navikt/core/tokens/darkside/util.ts

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>

* refactor: inline filter calls

* refactor: Better typing for as group declaration

* refactor: Avoid using objects as type definintions

* refactor: Inline semantic token check for roles

* refactor: date -> timestamp and NO locale

* refactor: token -> tokens

* refactor: removed redundant redaclaration of token name in test

* refactor: Avoid extra tests for same check

---------

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>
2024-09-27 12:35:42 +02:00
Ken 9f9bdcc645 bug: Fixed old test for global tokens 2024-09-26 19:13:38 +02:00
Ken 82bdf8075a [Tokens]: Update darkmode tokens and separate config support
feat: Updated darkmode tokens
feat: Split global color config into separate files
2024-09-26 19:09:01 +02:00
Julian Nymark 410e543825 🎨 [referansesider] minside eslint 2024-09-26 15:47:29 +02:00
Julian Nymark 40308e0e77 🎨 [referansesider] minside dokumentarkiv 2024-09-26 15:39:02 +02:00
Julian Nymark fff309b573 💄 [referansesider] minside NotificationsPanel lightmode match figma 2024-09-26 14:44:44 +02:00
Julian Nymark fe7c2de8fa 💄 [referansesider] minside PassiveCards++ 2024-09-26 14:37:42 +02:00
Julian Nymark 6fedea0ba4 💄 [referansesider] minside PassiveCards 2024-09-25 15:02:05 +02:00
Halvor HauganandKen 9811327509 [aksel.nav.no] Adjust examples of Switch (#3175)
---------

Co-authored-by: Ken <26967723+KenAJoh@users.noreply.github.com>
2024-09-25 14:21:19 +02:00
Ken cf2034f914 [Aksel.nav.no] Open all Accordions when searched (#3179)
* feat: Open all Accordions when searched

* refactor: Type node as possibly undefined
2024-09-25 14:19:15 +02:00
dependabot[bot] 9e5e7f8fdc build(deps): Bump rollup from 3.29.4 to 3.29.5 (#3178)
Bumps [rollup](https://github.com/rollup/rollup) from 3.29.4 to 3.29.5.
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rollup/rollup/compare/v3.29.4...v3.29.5)

---
updated-dependencies:
- dependency-name: rollup
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-25 13:49:55 +02:00
Ken e9dc171d74 Referansesider: Dynamic route-list generation for header and homepage 2024-09-25 13:25:43 +02:00
Julian Nymark 544b80eeae 💄 [referansesider] Minside Cards 2024-09-25 13:17:10 +02:00
Julian Nymark 4358b53095 🎨 [referansesider] move Styled components to top layer++ 2024-09-25 12:07:57 +02:00
Julian Nymark de57099b09 🎨 [referansesider] move Styled components to top layer 2024-09-25 11:59:57 +02:00
Ken 5a97cb422d feat: Add cache-control to index.html metadata referansesider 2024-09-25 11:16:03 +02:00
Ken 67fb3bb3a1 feat: Added theme switcher for referansesider 2024-09-25 10:52:03 +02:00
Ken 7bdd5cb748 bug: Fixes darkmode cascading for darkside tokens 2024-09-25 10:10:24 +02:00
github-actions[bot]andgithub-actions[bot] 62bcab1ab0 Version Packages (#3170)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-09-25 09:36:07 +02:00
Halvor Haugan 61e60d9556 Modify changeset text for Accordion change 2024-09-24 17:17:18 +02:00
Halvor Haugan 9c1eba4450 Accordion: Remove position:relative to fix popover clipping 2024-09-24 16:53:46 +02:00
Julian Nymark 63986d9872 💄 [referansesider] remove overflow 2024-09-24 16:43:04 +02:00
Ken 761c8ef64f refactor: Update tokens use in Piktogram for sykepenger page 2024-09-24 16:31:30 +02:00
Ken 4b86b555d8 feat: Referansesider now properly handles nested routing 2024-09-24 16:10:58 +02:00
Julian Nymark 8e1e294fda 💄 [referansesider] minside add icons 2024-09-24 15:51:55 +02:00
Halvor Haugan f71594e477 ErrorSummary: Remove aria-attributes. (#3171) 2024-09-24 15:41:49 +02:00
Julian Nymark d2a89851cd 💄 [referansesider] responsive design fix 2024-09-24 15:31:25 +02:00
Ken d27da71304 feat: Refactored to use more tokens in referansesider 2024-09-24 15:26:19 +02:00
Julian Nymark fcf17fc750 💄 [referansesider] minside card CSS 2024-09-24 15:24:41 +02:00
Julian Nymark e1b091358b 🎨 [referansesider] add content to minside 2024-09-24 15:15:15 +02:00
dependabot[bot] 988ad39ad1 build(deps): Bump rollup in /examples/referansesider (#3173)
Bumps [rollup](https://github.com/rollup/rollup) from 4.21.3 to 4.22.4.
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rollup/rollup/compare/v4.21.3...v4.22.4)

---
updated-dependencies:
- dependency-name: rollup
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-24 14:00:52 +02:00
Ken 524c87e3bd feat: Update referansesider header fontsize 2024-09-24 13:54:48 +02:00
Ken 8cf6123656 feat: Created /komponenter route for component-testing, refactored button-component
feat: Use func for sykepenger function
2024-09-24 13:32:24 +02:00
Julian Nymark 866e6a168c 💄 [referansesider] make sykepenger more responsive 2024-09-24 13:16:47 +02:00
Ken bc2be15c55 Update referansesider
- feat: Refactor to use aksel-icons package
- refactor: use google import for font instead of inline files
2024-09-24 13:06:55 +02:00
Julian Nymark 4e6fc073fe 🐛 [referansesider] only have tanstack router devtools in dev mode 2024-09-24 12:59:56 +02:00
Ken e895c691ce [Referansesider] SPA deploy to aksel-referansesider.ansatt.dev.nav.no (#3174)
* bug: Fix build-script

* feat: Workflow for SPA deploy of referansesider

* feat: Add workflow dispatch to SPA deploy
2024-09-24 12:40:08 +02:00
Halvor Haugan 186c0fec07 🆙 Upgrade some packages (#3165) 2024-09-23 17:24:04 +02:00
Ken 746a58b663 feat: Updated darkside tokens with figma 2024-09-23 16:30:13 +02:00
Julian Nymark d767aadde3 🎨 [referansesider] add crude dekoratør 2024-09-23 14:02:30 +02:00
KenandHalvor Haugan 4359428b40 [Pagination] Deprecated page-prop, synced design with Figma (#3164)
* feat: Mark page-prop as deprecated in pagination

* feat: Mark page-prop as deprecated in pagination with better comment

* feat: Synced pagination with Figma

* memo: Changeset

* memo: Add classes to deprecationlist in stylelint config

* memo: changeset for stylelint

* memo: changeset for stylelint

* Update @navikt/aksel-stylelint/src/deprecations.ts

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>

* Update .changeset/thirty-snakes-doubt.md

---------

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>
2024-09-23 12:28:52 +02:00
Halvor Haugan d583276428 Combobox: 🏷️ Better typing for maxSelected prop (#3169) 2024-09-23 10:07:06 +02:00
github-actions[bot]andgithub-actions[bot] 0d29a0708a Version Packages (#3151)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-09-20 10:33:33 +02:00
Vegard Haugstvedt d6b685c4c5 Bugfix/combobox list items with multiple spaces get invalid (#3162)
* Fix issue with whitespace in the id attribute for options with multiple spaces

* Add changeset
2024-09-20 09:32:34 +02:00
Julian Nymark 17eaf6139b 🎨 [referansesider] sykepenger++ 2024-09-20 00:38:18 +02:00
Julian Nymark f0820f4f89 🎨 [referansesider] sykepenger++ 2024-09-20 00:38:18 +02:00
Halvor Haugan cd9dc047ed Upgrade dockerimage (#3160) 2024-09-19 15:06:56 +02:00
Julian Nymark bc711c9653 💄 [referansesider] css tweaks for Accordion 2024-09-19 13:00:01 +02:00
Julian Nymark 5fd1d385cf 🎨 [referansesider] add PillLink 2024-09-19 12:22:13 +02:00
dependabot[bot]andHalvor Haugan f44acf4216 build(deps-dev): Bump vite in /examples/referansesider (#3154)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 5.4.5 to 5.4.6.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v5.4.6/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v5.4.6/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Halvor Haugan <halvor.haugan@nav.no>
2024-09-19 10:47:21 +02:00
Julian Nymark 302eed3908 💄 [referansesider] use new tokens 👏 2024-09-18 17:08:39 +02:00
Julian Nymark 24bec11799 💄 [referansesider] Accordion 2024-09-18 16:56:39 +02:00
KenandHalvor Haugan 72b2b3875b [Tokens] Updated to new config (#3157)
* feat: Update style-dictionary to v4

* feat: Rewritten tokens to typescript

* feat: Update to new token config

* refactor: removed unused types

* feat: Remove 'A'-prefix in js token

* update: Lock update

* testing: Updated tests to correctly mirror wanted behaviour

* refactor: Removed output fallbacks

* Update @navikt/core/tokens/darkside/tokens/contrast.ts

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>

* refactor: Update white definition in contrast

* refactor: Remove duplicate global color definition

* refactor: Avoid accumulator spread in reduce

* refactor: rename 'mode' -> 'theme'

* Update @navikt/core/tokens/darkside/sd-format.ts

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>

* feat: Added comment support to JS-tokens

* Update @navikt/core/tokens/darkside/tests/validate-config.test.ts

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>

* refactor: Use correct config in tests

* Update @navikt/core/tokens/darkside/util.ts

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>

* feat: Added returnType for semanticTokensForAllRolesConfig

* feat: Types token configurations

* feat: Updated color-scale to latest figma-update

* feat: Types mergeConfig function

---------

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>
2024-09-18 16:43:42 +02:00
Halvor Haugan e023ace28d Adjust examples of Accordion (#3159) 2024-09-18 16:06:33 +02:00
Julian Nymark 0129159812 🚚 [referansesider] consistent file naming 2024-09-18 15:48:42 +02:00
Julian Nymark 72fd005990 🎨 [referansesider] clsx dep + more content 2024-09-18 15:41:32 +02:00
Julian Nymark 104427d7ef 🎨 [referansesider] more work on Sykepenger 2024-09-18 13:57:10 +02:00
Julian Nymark 996118532b ➕ [referansesider] tw-merge 2024-09-18 13:56:31 +02:00
Julian Nymark 1cdf2c93a8 ✨ [referansesider] add icon 2024-09-18 13:55:51 +02:00
Julian Nymark 82e66e2a4b ✨ [referansesider] add icon 2024-09-18 13:55:41 +02:00
Julian Nymark 03495f8343 💄 [referansesider] adjust sykepenger header 2024-09-18 10:40:51 +02:00
KenandHalvor Haugan 17031eafbe [Tokens] Updated config to Style-dictionary v4, rewritten to typescript (#3156)
* feat: Update style-dictionary to v4

* feat: Rewritten tokens to typescript

* Update @navikt/core/tokens/config/build.ts

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>

* Update @navikt/core/tokens/package.json

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>

* update: Lock update

---------

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>
2024-09-18 10:17:41 +02:00
Julian Nymark fe3c42282a 🎨 [referansesider] add sykepenger header 2024-09-18 09:58:31 +02:00
Julian Nymark 7defbd9163 💄 [referansesider] remove broken negative margin calc css 2024-09-17 16:13:45 +02:00
Julian Nymark 4a402557f6 🎨 [referansesider] more scaffolding, remove unused CSS 2024-09-17 16:12:24 +02:00
Halvor Haugan f7ff964162 LanguageProvider: Remove spreading of empty object (#3153) 2024-09-17 15:28:41 +02:00
Julian Nymark 6bad72e891 🔥 [referansesider] remove generated file from git 2024-09-17 14:18:49 +02:00
Julian Nymark b0b493bc08 ➕ [referansesider] add tailwindcss 2024-09-17 14:13:36 +02:00
Julian Nymark 0720f22467 ➕ [referansesider] add tailwindcss 2024-09-17 14:11:00 +02:00
Halvor Haugan f4137e4df8 Adjust default story on ExpansionCard 2024-09-17 14:01:32 +02:00
Julian Nymark 730538cfb4 🎨 [referansesider] add router 2024-09-17 13:35:19 +02:00
Halvor Haugan a63c3792cc Simplify PR template and add guideline about changeset message (#3138) 2024-09-16 15:55:04 +02:00
Julian Nymark dd03bd8705 🚧 [referansesider] add example for variant in styled-components 2024-09-16 15:34:16 +02:00
Julian Nymark 97eec24ae0 🚧 [referansesider] do not use existing components & CSS 2024-09-16 15:26:06 +02:00
Julian Nymark 09e4f70365 🚧 [referansesider] use local dependencies for react as well 2024-09-16 13:56:02 +02:00
Julian Nymark ce694fa37c 🚧 [referansesider] use local dependencies for css & tokens 2024-09-16 13:50:53 +02:00
Julian Nymark 7f27e19032 🚧 [referansesider] correctly import design token 2024-09-16 13:21:35 +02:00
Julian Nymark 12f6ae9134 🚧 [referansesider] use styled-components, try to import our tokens 2024-09-16 13:13:42 +02:00
Julian Nymark 3c6459305e 🚧 [referansesider] add aksel dependencies 2024-09-16 12:47:26 +02:00
Julian Nymark 60cf2b863b ✨ (referansesider) init vite project 2024-09-16 12:19:26 +02:00
Halvor Haugan 78779fbb56 🆙 Upgrade to Storybook 8.3 (#3150) 2024-09-16 09:53:28 +02:00
SebastianJarsve 59156e603c Fix link in CONTRIBUTING.md (#3152) 2024-09-16 09:42:36 +02:00
Julian Nymark 057bfe85be 💄 tweak CSS for list icons (#3148) 2024-09-13 16:17:51 +02:00
github-actions[bot]andgithub-actions[bot] d2424ec22a Version Packages (#3149)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-09-13 14:03:22 +02:00
1c11a6a3b9 Aksel v7 (#3139)
* Tooltip labeling (#3094)

* feat: Better labeling of Tooltip

* feat: Better keyshortcuts for screenreaders in Tooltip

* memo: Updated story

* bug: Better error logging for example-parsing

* refactor: describeChild -> describesChild

* fire: Removed extra story

* bug: removed extra tabIndex

* memo: Update Tooltip demo description

* Update aksel.nav.no/website/pages/eksempler/tooltip/labeling.tsx

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>

* refactor: Updated defaultValue for describesChild

* bug: removed Tooltip prop from ToggleGroup

---------

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>

* Tailwind: Fixed 'screen' -> 'screens' bug to properly adopt breakpoints. (#3119)

* 💥 Screen -> Screens in tailwind-config

* refactor: Adopt updated screens-config in Aksel.nav.no project

* Icons: Removed old and renamed icons (#3120)

* 💥 Removed renamed icons

* ErrorSummary: Add fallback for heading + better focus handling (#3140)

Co-authored-by: Ken <ken.aleksander@gmail.com>
Co-authored-by: Ken <26967723+KenAJoh@users.noreply.github.com>

Co-authored-by: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com>

* feat: Added composeEventHandlers to onFocus in ErrorSummary

* memo: Removed inaccurate description for tooltip demo

* feat: Omitted tabIndex from ErrorSummary

---------

Co-authored-by: Ken <26967723+KenAJoh@users.noreply.github.com>
Co-authored-by: Ken <ken.aleksander@gmail.com>
2024-09-13 13:48:56 +02:00
Julian NymarkandKen 46a14b19dd translations in Provider (#3136)
* 🚧 translations in Provider

* ♻️ consume providerContext translations in useI18n + example usage (FormProgress)

* changeset

* 🎨 keep component level translations

* ♻️ extract language provider into own provider

* 📝 update changeset doc

* 🎨 undo all changes to original Provider

* 📝 changeset text

* ✅ update test for i18n changes

* refactor: Moved location of LanguageProvider, removed changeset

---------

Co-authored-by: Ken <ken.aleksander@gmail.com>
2024-09-12 15:36:04 +02:00
311 changed files with 19015 additions and 11112 deletions

No files matched your search

+26 -13
View File
@@ -1,4 +1,11 @@
// TODO: Convert to new format: https://eslint.org/docs/latest/use/configure/migration-guide
/**
* TODO:
* - Convert to new format (v9): https://eslint.org/docs/latest/use/configure/migration-guide
* - Look into opinionated stylistic plugin
* - Replace @typescript-eslint/recommended with @typescript-eslint/recommended-type-checked
* - We should add "plugin:react/jsx-runtime", but not sure if this will cause problems for projects not using the new JSX transform
* - Consider adding the rule "id-length"
*/
module.exports = {
env: {
browser: true,
@@ -8,15 +15,13 @@ module.exports = {
extends: [
"eslint:recommended",
"plugin:react/recommended",
//"plugin:react/jsx-runtime", // Not sure if this will cause problems for projects not using the new JSX transform
"plugin:react-hooks/recommended",
"plugin:jsx-a11y/recommended",
"plugin:import/recommended",
"plugin:import/typescript",
"plugin:storybook/recommended",
// TODO: Look into opinionated stylistic plugin
// TODO: Replace @typescript-eslint/recommended with @typescript-eslint/recommended-type-checked
],
/* Allows eslint-plugin-react to detect installed react-version */
settings: { react: { version: "detect" } },
rules: {
"import/no-unresolved": "off",
@@ -26,12 +31,6 @@ module.exports = {
],
"array-callback-return": "error",
"object-shorthand": "error",
// TODO: Consider adding the rule "id-length"
// Temporary:
"react/prop-types": "off",
"react/display-name": "off",
"import/no-named-as-default": "off",
// "import/no-cycle": [1],
"no-else-return": "error",
"no-console": [
"warn",
@@ -53,7 +52,12 @@ module.exports = {
],
},
],
/* Temporarily turned off until code is updated */
"react/prop-types": "off",
"react/display-name": "off",
"import/no-named-as-default": "off",
},
/* https://eslint.org/docs/latest/use/configure/rules#report-unused-eslint-disable-comments */
reportUnusedDisableDirectives: true,
overrides: [
{
@@ -66,15 +70,23 @@ module.exports = {
files: ["**/*.ts?(x)"],
extends: ["plugin:@typescript-eslint/recommended"],
rules: {
"@typescript-eslint/no-shadow": ["error", { hoist: "all" }], // TODO: Consider { builtinGlobals: true }
/*
* TODO:
* - Consider { builtinGlobals: true }
*/
"@typescript-eslint/no-shadow": ["error", { hoist: "all" }],
"@typescript-eslint/no-explicit-any": "off", // Temporary
"@typescript-eslint/array-type": "error",
},
},
{
files: ["**/*.test.*", "**/__tests__/*"],
plugins: ["vitest"],
extends: ["plugin:vitest/recommended", "plugin:testing-library/react"],
plugins: ["@vitest"],
extends: [
"plugin:testing-library/react",
/* Needed to support v8 eslint config-syntax */
"plugin:@vitest/legacy-recommended",
],
},
{
@@ -153,5 +165,6 @@ module.exports = {
"**/codemod/**/*.js",
"!.storybook",
"**/playwright-report/**",
"**/tokens/**/plugin.js",
],
};
+13 -41
View File
@@ -1,45 +1,17 @@
### Description
<!-- PR description/motivation
add links to project-tasks, slack discussions etc here
-->
<!-- PR description/motivation, summary of changes, links to issue/slack discussion etc. -->
### Change summary
### Component Checklist 📝
<!-- Short summary of changes in PR
- added variant x
- fixed bug in y
-->
### PR Checklist 📝 (Remove fields after check!)
#### New component? ✨
- Check that component-styling is correctly configured in `@navikt/core/css/config/_mappings.js`. This is needed for correct build and CDN upload.
- Check that styling is correctly exported from `@navikt/core/css/index.css`
- Check that correct tokens for component is documented in `@navikt/core/css/tokens.json`
- Check that only needed components and types are exported from `@navikt/core/react/src/index.ts`
- Check that component is exported from `@navikt/core/react/package.json`
- Add JSDoc to component (see other components for reference)
- Create storybook-stories for relevant component variations and compositions. Stories are used for [visual regression testing](https://www.chromatic.com/docs/), so make sure they are complete.
- Is the component sufficiently complex to warrant tests? Add some unit-tests for vitest.
#### Component-updates 🎉
- Revalidate if everything under `New component` is still accounted for
- Deprecating/removing a CSS class? Add it to `@navikt/aksel-stylelint/src/deprecations.ts` with a suitable description. This helps stylelint-users keep their code clean and bug-free.
#### Documentation 📝
- Add/update component-demos for component `aksel.nav.no/website/pages/eksempler`
- Create/Update documentation in sanity if needed
Note: Props, tokens and examples only updates to sanity on merge to main
#### Versioning 🏷️
- Run `yarn changeset` to generate a version-entry for change.
- - Bug/hotfix: Patch
- - New feature: Minor
- - Breaking change: Major
- Adding breaking changes? Consider adding a codemod for easier migration.
- Breaking changes also needs documentation under "Migration"-page on website
- [ ] JSDoc
- [ ] Examples
- [ ] Documentation
- [ ] Storybook
- [ ] Style mappings (`@navikt/core/css/config/_mappings.js`)
- [ ] Component tokens (`@navikt/core/css/tokens.json`)
- [ ] CSS class deprecations (`@navikt/aksel-stylelint/src/deprecations.ts`)
- [ ] Exports (`@navikt/core/react/src/index.ts` and `@navikt/core/react/package.json`)
- [ ] New component? CSS import (`@navikt/core/css/index.css`)
- [ ] Breaking change? Update migration guide. Consider codemod.
- [ ] Changeset (Format: `<Component>: <gitmoji?> <Text>.` E.g. "Button: :sparkles: Add feature xyz.")
+3
View File
@@ -34,6 +34,9 @@ jobs:
- name: Install dependencies
run: yarn
- name: Create empty .env file (Can be removed when env-file-if-exists is implemented in node v22)
run: echo "" > ./aksel.nav.no/website/.env
- name: Build application
env:
SANITY_READ: ${{ secrets.SANITY_READ }}
+6
View File
@@ -32,6 +32,9 @@ jobs:
yarn boot
yarn docgen
- name: Create empty .env file (Can be removed when env-file-if-exists is implemented in node v22)
run: echo "" > ./aksel.nav.no/website/.env
- name: Update sanity sync
env:
SANITY_WRITE: ${{ secrets.SANITY_WRITE }}
@@ -68,6 +71,9 @@ jobs:
- name: Tests
run: yarn workspace website test
- name: Create empty .env file (Can be removed when env-file-if-exists is implemented in node v22)
run: echo "" > ./aksel.nav.no/website/.env
- name: Build application
env:
SANITY_READ: ${{ secrets.SANITY_READ }}
+3
View File
@@ -23,6 +23,9 @@ jobs:
- name: Install dependencies
run: cd aksel.nav.no/website && yarn
- name: Create empty .env file (Can be removed when env-file-if-exists is implemented in node v22)
run: echo "" > ./aksel.nav.no/website/.env
- name: Export dataset
env:
SANITY_READ: ${{ secrets.SANITY_READ }}
+3
View File
@@ -31,6 +31,9 @@ jobs:
run: |
yarn boot
- name: Create empty .env file (Can be removed when env-file-if-exists is implemented in node v22)
run: echo "" > ./aksel.nav.no/website/.env
- name: Build application
env:
SANITY_READ: ${{ secrets.SANITY_READ }}
+50
View File
@@ -0,0 +1,50 @@
name: "Update remote token config for figma variables plugin"
on:
workflow_dispatch:
push:
branches:
- "main"
paths:
- "@navikt/core/tokens/**"
jobs:
upload:
runs-on: ubuntu-latest
permissions:
contents: "read"
id-token: "write"
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: lts/*
cache: yarn
- name: set-env for yarn install to @navikt scope
shell: bash
run: echo "NPM_AUTH_TOKEN=${{ secrets.READER_TOKEN }}" >> $GITHUB_ENV
- name: Install dependencies
run: yarn
- name: Build tokens
run: yarn workspace @navikt/ds-tokens build
- id: upload
uses: nais/deploy/actions/cdn-upload/v2@master
with:
team: designsystem
source: "./@navikt/core/tokens/figma-config.json"
destination: "./@navikt/tokens"
project_id: ${{ vars.NAIS_MANAGEMENT_PROJECT_ID }}
identity_provider: ${{ secrets.NAIS_WORKLOAD_IDENTITY_PROVIDER }}
source_keep_parent_name: false
no_cache_paths: "@navikt/tokens/figma-config.json"
- run: echo uploaded file ${{ steps.upload.outputs.uploaded }}
shell: bash
@@ -0,0 +1,37 @@
name: Deploy referansesider SPA
on:
workflow_dispatch:
push:
branches:
- main
jobs:
build-and-deploy:
runs-on: ubuntu-latest
permissions:
contents: "read"
id-token: "write"
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: lts/*
cache: yarn
- run: yarn install
env:
NPM_AUTH_TOKEN: ${{ secrets.READER_TOKEN }}
- run: yarn boot
- run: cd ./examples/referansesider && yarn && yarn build
- uses: nais/deploy/actions/spa-deploy/v2@master
with:
app: aksel-referansesider
team: designsystem
source: ./examples/referansesider/dist
ingress: https://aksel-referansesider.ansatt.dev.nav.no
environment: dev
project_id: ${{ vars.NAIS_MANAGEMENT_PROJECT_ID }}
identity_provider: ${{ secrets.NAIS_WORKLOAD_IDENTITY_PROVIDER }}
@@ -5,24 +5,11 @@ jobs:
execute:
runs-on: ubuntu-latest
permissions:
packages: "write"
contents: "read"
id-token: "write"
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 1
- uses: denoland/setup-deno@v1
with:
deno-version: v1.x
- name: Restore cache
uses: actions/cache@v4
with:
path: "**/node_modules"
key: ${{ runner.os }}-build-${{ github.sha }}
restore-keys: |
${{ runner.os }}-build-
- uses: nais/docker-build-push@v0
id: docker-push
with:
+18
View File
@@ -1,5 +1,23 @@
# @navikt/aksel-icons
## 7.2.1
## 7.2.0
## 7.1.2
## 7.1.1
## 7.1.0
## 7.0.1
## 7.0.0
### Major Changes
- Icons: Removed renamed icons. [See migration guide for changes](https://aksel.nav.no/grunnleggende/kode/migrering#194b60833d9e). ([#3139](https://github.com/navikt/aksel/pull/3139))
## 6.17.0
### Minor Changes
@@ -1,3 +1,4 @@
/* eslint-disable import/no-named-as-default-member */
import fastglob from "fast-glob";
import fs from "fs";
import jsYaml from "js-yaml";
@@ -21,8 +21,7 @@ describe(`Each icons has a valid code`, () => {
test(`has valid attributes on root-node`, () => {
const root = select(":root", iconAst);
const properties =
root && root.properties ? Object.keys(root.properties).sort() : [];
const properties = Object.keys(root?.properties ?? []).sort();
expect(properties).toStrictEqual(
["viewBox", "xmlns", "height", "width", "fill"].sort(),
@@ -31,45 +30,41 @@ describe(`Each icons has a valid code`, () => {
test(`has valid xml-attr`, () => {
const root = select(":root", iconAst);
const xmlns = root && root.properties ? root.properties.xmlns : null;
expect(xmlns).toBe("http://www.w3.org/2000/svg");
expect(root?.properties?.xmlns).toBe("http://www.w3.org/2000/svg");
});
test(`has valid viewbox`, () => {
const root = select(":root", iconAst);
const viewbox =
root && root.properties ? root.properties.viewBox : null;
expect(viewbox).toBe("0 0 24 24");
expect(root?.properties?.viewBox).toBe("0 0 24 24");
});
test(`root fill is none`, () => {
const root = select(":root", iconAst);
const fill = root && root.properties ? root.properties.fill : null;
expect(fill).toBe("none");
expect(root?.properties?.fill).toBe("none");
});
test(`has valid width and height`, () => {
const root = select(":root", iconAst);
const width = root && root.properties ? root.properties.width : null;
const height = root && root.properties ? root.properties.height : null;
expect(width).toBe("24");
expect(height).toBe("24");
expect(root?.properties?.width).toBe("24");
expect(root?.properties?.height).toBe("24");
});
test(`has valid stroke`, () => {
const nodes = selectAll("*", iconAst);
nodes.forEach((n) => {
n.properties?.stroke &&
if (n.properties?.stroke) {
expect(n.properties.stroke).toEqual("#23262A");
}
});
});
test(`has valid stroke-width`, () => {
const nodes = selectAll("*", iconAst);
nodes.forEach((n) => {
n.properties?.strokeWidth &&
if (n.properties?.strokeWidth) {
expect(n.properties?.strokeWidth).toEqual("1.5");
}
});
});
});
@@ -1,6 +1,7 @@
const file_key = "wEdyFjCQSBR3U7FvrMbPXa";
export const fetchIcons = async () => {
console.info("Fetching new icons from Figma...");
const data = await fetch(
`https://api.figma.com/v1/files/${file_key}/components`,
{
@@ -15,6 +16,10 @@ export const fetchIcons = async () => {
throw e.message;
});
if (data?.err) {
throw new Error(data.err);
}
if (!data?.meta?.components || data?.meta?.components.length === 0) {
throw new Error("Fant ingen publiserte ikoner");
}
@@ -6,7 +6,7 @@ export const resolveName = (icon) => {
if (isVariant) {
const variant = icon.name.replace("Variant=", "").replace("Stroke", "");
const actualName = icon["containing_frame"]?.["containingStateGroup"]?.name;
const actualName = icon.containing_frame?.containingStateGroup?.name;
const name = `${actualName}${variant}`;
return `${startCase(camelCase(name)).replace(/ /g, "")}.svg`;
}
+1 -2
View File
@@ -1,4 +1,3 @@
import { config } from "dotenv";
import { existsSync, mkdirSync, readdirSync, rmSync, writeFileSync } from "fs";
import { resolve } from "path";
import { fetchDownloadUrls, fetchIcon, fetchIcons } from "./fetch-icons.mjs";
@@ -6,7 +5,6 @@ import { resolveName } from "./icon-name.mjs";
import { makeConfig } from "./make-configs.mjs";
import { paginate } from "./paginate.mjs";
config();
/* https://www.figma.com/file/wEdyFjCQSBR3U7FvrMbPXa/Core-Icons-Next?node-id=277%3A1221&t=mUJzFvnsceYYXNL5-0 */
const iconFolder = "./icons";
@@ -16,6 +14,7 @@ if (!process.env.FIGMA_TOKEN) {
}
async function main() {
console.info("Started icon-update from Figma");
let icons = await fetchIcons();
const totalIcons = icons.length;
+1
View File
@@ -15,6 +15,7 @@ ymlList.forEach((file) => {
const ymlData = jsYaml.load(fs.readFileSync(`${basePath}/${file}`), {
schema: jsYaml.JSON_SCHEMA,
});
// biome-ignore lint/complexity/useOptionalChain: optional chain not supported in enviroment. Consider revriting to Typescript
if (ymlData.keywords && ymlData.keywords.includes("[ignore-docs]")) {
return;
}
@@ -18,7 +18,7 @@
"react-dom": "^18.0.0"
},
"devDependencies": {
"@figma/plugin-typings": "^1.84.0",
"@figma/plugin-typings": "^1.100.2",
"@svgr/core": "^8.1.0",
"@types/node": "^18.15.11",
"@types/postcss-url": "^10.0.4",
@@ -28,7 +28,7 @@
"postcss": "^8.4.31",
"postcss-url": "^10.1.3",
"typescript": "^5.1.6",
"vite": "^5.1.7",
"vite": "^5.4.6",
"vite-plugin-singlefile": "^1.0.0",
"vite-plugin-svgr": "^4.2.0"
}
@@ -109,7 +109,7 @@ const App = () => {
icon.removeEventListener("dragend", dragEvent);
}
};
}, [categories]);
}, []);
return (
<main tabIndex={-1} className="wrapper">
@@ -1,3 +0,0 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.06458 4.26481C7.76736 2.95822 9.85369 2.25 12 2.25C14.1463 2.25 16.2326 2.95821 17.9354 4.2648C19.6382 5.57139 20.8623 7.40334 21.4178 9.47651C21.9733 11.5497 21.8292 13.7482 21.0078 15.7312C20.1865 17.7141 18.7338 19.3706 16.875 20.4437C16.7027 20.5432 16.498 20.5702 16.3059 20.5187C16.1138 20.4672 15.9499 20.3415 15.8505 20.1692L12.7005 14.7133C12.601 14.541 12.5741 14.3363 12.6256 14.1442C12.677 13.952 12.8027 13.7882 12.975 13.6887C13.3468 13.4741 13.6373 13.1428 13.8016 12.7462C13.9658 12.3496 13.9947 11.9099 13.8836 11.4953C13.7725 11.0807 13.5276 10.7143 13.1871 10.453C12.8465 10.1916 12.4293 10.05 12 10.05C11.5707 10.05 11.1535 10.1916 10.8129 10.453C10.4724 10.7143 10.2275 11.0807 10.1164 11.4953C10.0053 11.9099 10.0342 12.3496 10.1984 12.7462C10.3627 13.1428 10.6533 13.4741 11.025 13.6887C11.1973 13.7882 11.323 13.952 11.3744 14.1442C11.4259 14.3363 11.399 14.541 11.2995 14.7133L8.14952 20.1692C8.05007 20.3415 7.88625 20.4672 7.69412 20.5187C7.50198 20.5702 7.29727 20.5432 7.125 20.4437C5.26625 19.3706 3.81354 17.7141 2.99218 15.7312C2.17082 13.7482 2.02672 11.5497 2.58223 9.47652C3.13773 7.40334 4.3618 5.5714 6.06458 4.26481ZM12 3.75C10.1839 3.75 8.41854 4.34926 6.97772 5.45484C5.53691 6.56041 4.50116 8.11052 4.03112 9.86474C3.56107 11.619 3.683 13.4793 4.378 15.1571C4.97686 16.6029 5.97237 17.8436 7.24256 18.7401L9.66674 14.5413C9.29868 14.2034 9.00613 13.7874 8.81262 13.3203C8.52199 12.6186 8.471 11.8407 8.66756 11.1071C8.86412 10.3735 9.29725 9.72526 9.89978 9.26293C10.5023 8.8006 11.2405 8.55 12 8.55C12.7595 8.55 13.4977 8.8006 14.1002 9.26293C14.7028 9.72526 15.1359 10.3735 15.3324 11.1071C15.529 11.8407 15.478 12.6186 15.1874 13.3203C14.9939 13.7874 14.7013 14.2034 14.3333 14.5413L16.7574 18.7401C18.0276 17.8436 19.0231 16.6029 19.622 15.1571C20.317 13.4793 20.4389 11.619 19.9689 9.86474C19.4988 8.11052 18.4631 6.56041 17.0223 5.45483C15.5815 4.34926 13.8161 3.75 12 3.75Z" fill="#23262A"/>
</svg>

Before

Width:  |  Height:  |  Size: 2.0 KiB

@@ -1,19 +0,0 @@
name: BeaconSignals
category: Development
sub_category: Development
keywords:
- location
- tracking
- identification
- signaling
- broadcasting
- detection
- lokalisering
- sporing
- identifikasjon
- signalisering
- kringkasting
- deteksjon
variant: Stroke
updated_at: 04.12.2023
created_at: 07.03.2023
@@ -1,3 +0,0 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.06458 4.26481C7.76736 2.95822 9.85369 2.25 12 2.25C14.1463 2.25 16.2326 2.95821 17.9354 4.2648C19.6382 5.57139 20.8623 7.40334 21.4178 9.47651C21.9733 11.5497 21.8292 13.7482 21.0078 15.7312C20.1865 17.7141 18.7338 19.3706 16.875 20.4437C16.7027 20.5432 16.498 20.5702 16.3059 20.5187C16.1138 20.4672 15.9499 20.3415 15.8505 20.1692L12.7005 14.7133C12.601 14.541 12.5741 14.3363 12.6256 14.1442C12.677 13.952 12.8027 13.7882 12.975 13.6887C13.3468 13.4741 13.6373 13.1428 13.8016 12.7462C13.9658 12.3496 13.9947 11.9099 13.8836 11.4953C13.7725 11.0807 13.5276 10.7143 13.1871 10.453C12.8465 10.1916 12.4293 10.05 12 10.05C11.5707 10.05 11.1535 10.1916 10.8129 10.453C10.4724 10.7143 10.2275 11.0807 10.1164 11.4953C10.0053 11.9099 10.0342 12.3496 10.1984 12.7462C10.3627 13.1428 10.6533 13.4741 11.025 13.6887C11.1973 13.7882 11.323 13.952 11.3744 14.1442C11.4259 14.3363 11.399 14.541 11.2995 14.7133L8.14952 20.1692C8.05007 20.3415 7.88625 20.4672 7.69412 20.5187C7.50198 20.5702 7.29727 20.5432 7.125 20.4437C5.26625 19.3706 3.81354 17.7141 2.99218 15.7312C2.17082 13.7482 2.02672 11.5497 2.58223 9.47652C3.13773 7.40334 4.3618 5.5714 6.06458 4.26481Z" fill="#23262A"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

@@ -1,19 +0,0 @@
name: BeaconSignalsFill
category: Development
sub_category: Development
keywords:
- location
- tracking
- identification
- signaling
- broadcasting
- detection
- lokalisering
- sporing
- identifikasjon
- signalisering
- kringkasting
- deteksjon
variant: Fill
updated_at: 04.12.2023
created_at: 07.03.2023
-3
View File
@@ -1,3 +0,0 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.25 3C10.25 2.58579 10.5858 2.25 11 2.25H21C21.4142 2.25 21.75 2.58579 21.75 3V21C21.75 21.4142 21.4142 21.75 21 21.75H3C2.58579 21.75 2.25 21.4142 2.25 21V13C2.25 12.5858 2.58579 12.25 3 12.25H10.25V3ZM13.75 13C13.75 12.5858 13.4142 12.25 13 12.25H11.75V3.75H20.25V20.25H13.75V13ZM12.25 13.75V20.25H3.75V13.75H12.25ZM18.75 5.5C18.75 5.08579 18.4142 4.75 18 4.75C17.5858 4.75 17.25 5.08579 17.25 5.5V6.5C17.25 6.91421 17.5858 7.25 18 7.25C18.4142 7.25 18.75 6.91421 18.75 6.5V5.5ZM5.5 15.25C5.08579 15.25 4.75 15.5858 4.75 16C4.75 16.4142 5.08579 16.75 5.5 16.75H6.5C6.91421 16.75 7.25 16.4142 7.25 16C7.25 15.5858 6.91421 15.25 6.5 15.25H5.5ZM7.75 16C7.75 15.5858 8.08579 15.25 8.5 15.25H9.5C9.91421 15.25 10.25 15.5858 10.25 16C10.25 16.4142 9.91421 16.75 9.5 16.75H8.5C8.08579 16.75 7.75 16.4142 7.75 16ZM18.75 9.5C18.75 9.08579 18.4142 8.75 18 8.75C17.5858 8.75 17.25 9.08579 17.25 9.5V10.5C17.25 10.9142 17.5858 11.25 18 11.25C18.4142 11.25 18.75 10.9142 18.75 10.5V9.5ZM18 12.75C18.4142 12.75 18.75 13.0858 18.75 13.5V14.5C18.75 14.9142 18.4142 15.25 18 15.25C17.5858 15.25 17.25 14.9142 17.25 14.5V13.5C17.25 13.0858 17.5858 12.75 18 12.75Z" fill="#23262A"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

-8
View File
@@ -1,8 +0,0 @@
name: Buldings2
category: Workplace
sub_category: Offices
keywords:
- "[ignore-docs]"
variant: Stroke
updated_at: 16.01.2024
created_at: 07.03.2023
@@ -1,3 +0,0 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M11 2.25C10.5858 2.25 10.25 2.58579 10.25 3V10.5C10.25 10.6381 10.3619 10.75 10.5 10.75H13C14.2426 10.75 15.25 11.7574 15.25 13V21.5C15.25 21.6381 15.3619 21.75 15.5 21.75H21C21.4142 21.75 21.75 21.4142 21.75 21V3C21.75 2.58579 21.4142 2.25 21 2.25H11ZM18 4.75C18.4142 4.75 18.75 5.08579 18.75 5.5V6.5C18.75 6.91421 18.4142 7.25 18 7.25C17.5858 7.25 17.25 6.91421 17.25 6.5V5.5C17.25 5.08579 17.5858 4.75 18 4.75ZM18.75 9.5C18.75 9.08579 18.4142 8.75 18 8.75C17.5858 8.75 17.25 9.08579 17.25 9.5V10.5C17.25 10.9142 17.5858 11.25 18 11.25C18.4142 11.25 18.75 10.9142 18.75 10.5V9.5ZM18 12.75C18.4142 12.75 18.75 13.0858 18.75 13.5V14.5C18.75 14.9142 18.4142 15.25 18 15.25C17.5858 15.25 17.25 14.9142 17.25 14.5V13.5C17.25 13.0858 17.5858 12.75 18 12.75ZM3 12.25C2.58579 12.25 2.25 12.5858 2.25 13V21C2.25 21.4142 2.58579 21.75 3 21.75H13C13.4142 21.75 13.75 21.4142 13.75 21V13C13.75 12.5858 13.4142 12.25 13 12.25H3ZM5.5 15.25C5.08579 15.25 4.75 15.5858 4.75 16C4.75 16.4142 5.08579 16.75 5.5 16.75H6.5C6.91421 16.75 7.25 16.4142 7.25 16C7.25 15.5858 6.91421 15.25 6.5 15.25H5.5ZM7.75 16C7.75 15.5858 8.08579 15.25 8.5 15.25H9.5C9.91421 15.25 10.25 15.5858 10.25 16C10.25 16.4142 9.91421 16.75 9.5 16.75H8.5C8.08579 16.75 7.75 16.4142 7.75 16Z" fill="#23262A"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

@@ -1,8 +0,0 @@
name: Buldings2Fill
category: Workplace
sub_category: Offices
keywords:
- "[ignore-docs]"
variant: Fill
updated_at: 16.01.2024
created_at: 07.03.2023
-3
View File
@@ -1,3 +0,0 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.25 3C6.25 2.58579 6.58579 2.25 7 2.25H17C17.4142 2.25 17.75 2.58579 17.75 3V9.25H21C21.4142 9.25 21.75 9.58579 21.75 10V21C21.75 21.4142 21.4142 21.75 21 21.75H3C2.58579 21.75 2.25 21.4142 2.25 21V10C2.25 9.58579 2.58579 9.25 3 9.25H6.25V3ZM17.75 20.25V10.75H20.25V20.25H17.75ZM16.25 3.75V20.25H7.75V3.75H16.25ZM6.25 10.75V20.25H3.75V10.75H6.25ZM10 5.75C10.4142 5.75 10.75 6.08579 10.75 6.5V8.5C10.75 8.91421 10.4142 9.25 10 9.25C9.58579 9.25 9.25 8.91421 9.25 8.5V6.5C9.25 6.08579 9.58579 5.75 10 5.75ZM13 5.75C13.4142 5.75 13.75 6.08579 13.75 6.5V8.5C13.75 8.91421 13.4142 9.25 13 9.25C12.5858 9.25 12.25 8.91421 12.25 8.5V6.5C12.25 6.08579 12.5858 5.75 13 5.75ZM10.75 12.5C10.75 12.0858 10.4142 11.75 10 11.75C9.58579 11.75 9.25 12.0858 9.25 12.5V14.5C9.25 14.9142 9.58579 15.25 10 15.25C10.4142 15.25 10.75 14.9142 10.75 14.5V12.5ZM13 11.75C13.4142 11.75 13.75 12.0858 13.75 12.5V14.5C13.75 14.9142 13.4142 15.25 13 15.25C12.5858 15.25 12.25 14.9142 12.25 14.5V12.5C12.25 12.0858 12.5858 11.75 13 11.75Z" fill="#23262A"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

-8
View File
@@ -1,8 +0,0 @@
name: Buldings3
category: Workplace
sub_category: Offices
keywords:
- "[ignore-docs]"
variant: Stroke
updated_at: 16.01.2024
created_at: 07.03.2023
@@ -1,3 +0,0 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M11 2.25C10.5858 2.25 10.25 2.58579 10.25 3V10.5C10.25 10.6381 10.3619 10.75 10.5 10.75H13C14.2426 10.75 15.25 11.7574 15.25 13V21.5C15.25 21.6381 15.3619 21.75 15.5 21.75H21C21.4142 21.75 21.75 21.4142 21.75 21V3C21.75 2.58579 21.4142 2.25 21 2.25H11ZM18 4.75C18.4142 4.75 18.75 5.08579 18.75 5.5V6.5C18.75 6.91421 18.4142 7.25 18 7.25C17.5858 7.25 17.25 6.91421 17.25 6.5V5.5C17.25 5.08579 17.5858 4.75 18 4.75ZM18.75 9.5C18.75 9.08579 18.4142 8.75 18 8.75C17.5858 8.75 17.25 9.08579 17.25 9.5V10.5C17.25 10.9142 17.5858 11.25 18 11.25C18.4142 11.25 18.75 10.9142 18.75 10.5V9.5ZM18 12.75C18.4142 12.75 18.75 13.0858 18.75 13.5V14.5C18.75 14.9142 18.4142 15.25 18 15.25C17.5858 15.25 17.25 14.9142 17.25 14.5V13.5C17.25 13.0858 17.5858 12.75 18 12.75ZM3 12.25C2.58579 12.25 2.25 12.5858 2.25 13V21C2.25 21.4142 2.58579 21.75 3 21.75H13C13.4142 21.75 13.75 21.4142 13.75 21V13C13.75 12.5858 13.4142 12.25 13 12.25H3ZM5.5 15.25C5.08579 15.25 4.75 15.5858 4.75 16C4.75 16.4142 5.08579 16.75 5.5 16.75H6.5C6.91421 16.75 7.25 16.4142 7.25 16C7.25 15.5858 6.91421 15.25 6.5 15.25H5.5ZM7.75 16C7.75 15.5858 8.08579 15.25 8.5 15.25H9.5C9.91421 15.25 10.25 15.5858 10.25 16C10.25 16.4142 9.91421 16.75 9.5 16.75H8.5C8.08579 16.75 7.75 16.4142 7.75 16Z" fill="#23262A"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

@@ -1,8 +0,0 @@
name: Buldings3Fill
category: Workplace
sub_category: Offices
keywords:
- "[ignore-docs]"
variant: Fill
updated_at: 16.01.2024
created_at: 07.03.2023
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/aksel-icons",
"version": "6.17.0",
"version": "7.2.1",
"author": "Aksel | NAV",
"homepage": "https://aksel.nav.no/ikoner",
"repository": {
@@ -62,7 +62,7 @@
"update-metadata": "node config/metadata.js",
"write-packagejson": "echo '{\"type\": \"module\"}' > dist/react/esm/package.json",
"build": "yarn copy && yarn create-icons && concurrently \"tsc\" \"tsc -p tsconfig.esm.json && tsc-alias -p tsconfig.esm.json && yarn write-packagejson\" && node config/cleanTypes.js && yarn update-metadata && yarn parse-svg",
"fetch-new:icons": "node config/figma/index.mjs",
"fetch-new:icons": "tsx --env-file=.env config/figma/index.mjs",
"zip:icons": "node config/zip.js",
"test": "vitest run",
"test:watch": "vitest watch"
@@ -73,7 +73,6 @@
"concurrently": "7.2.1",
"copyfiles": "^2.4.1",
"cross-zip-cli": "1.0.0",
"dotenv": "^10.0.0",
"fast-glob": "3.2.11",
"hast-util-select": "5.0.5",
"js-yaml": "^4.1.0",
@@ -83,6 +82,7 @@
"react": "^18.0.0",
"rehype-parse": "8.0.4",
"tsc-alias": "1.8.8",
"tsx": "^4.7.1",
"typescript": "^5.1.6",
"unified": "10.1.2",
"vitest": "^1.2.2"
+22
View File
@@ -1,5 +1,27 @@
# @navikt/aksel-stylelint
## 7.2.1
## 7.2.0
## 7.1.2
## 7.1.1
### Patch Changes
- List: :boom: Removed class names "navds-list--nested" and "navds-list\_\_item-content" ([#3184](https://github.com/navikt/aksel/pull/3184))
## 7.1.0
### Minor Changes
- Pagination: :boom: Added some classNames to list of deprecated (removed) classes. ([#3164](https://github.com/navikt/aksel/pull/3164))
## 7.0.1
## 7.0.0
## 6.17.0
## 6.16.3
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/aksel-stylelint",
"version": "6.17.0",
"version": "7.2.1",
"author": "Aksel | NAV",
"homepage": "https://aksel.nav.no/grunnleggende/kode/stylelint",
"repository": {
@@ -35,8 +35,8 @@
"dev": "yarn watch:lint"
},
"devDependencies": {
"@navikt/ds-css": "^6.17.0",
"@navikt/ds-tokens": "^6.17.0",
"@navikt/ds-css": "^7.2.1",
"@navikt/ds-tokens": "^7.2.1",
"concurrently": "7.2.1",
"postcss-selector-parser": "^6.0.13",
"postcss-value-parser": "^4.2.0",
@@ -60,4 +60,16 @@ export const deprecations: DeprecatedList = [
classes: ["navds-textarea__wrapper"],
message: "Removed in v6.0.0",
},
{
classes: [
"navds-pagination__prev-next-icon",
"navds-pagination__next-text",
"navds-pagination__prev-text",
],
message: "These classes had no effect and were removed in v7.1.0",
},
{
classes: ["navds-list--nested", "navds-list__item-content"],
message: "Removed in v7.1.1",
},
];
+49
View File
@@ -1,5 +1,54 @@
# @navikt/aksel
## 7.2.1
### Patch Changes
- Updated dependencies [[`6ddea4eaf`](https://github.com/navikt/aksel/commit/6ddea4eaf2e37f20f93d75e1a3a327b038fb209b)]:
- @navikt/ds-css@7.2.1
## 7.2.0
### Patch Changes
- Updated dependencies []:
- @navikt/ds-css@7.2.0
## 7.1.2
### Patch Changes
- Updated dependencies [[`95c84e1d0`](https://github.com/navikt/aksel/commit/95c84e1d014d880bc22eb0053a875771e8399540)]:
- @navikt/ds-css@7.1.2
## 7.1.1
### Patch Changes
- Updated dependencies [[`ca1d9be88`](https://github.com/navikt/aksel/commit/ca1d9be88f45f936ee8546af146f8783d8c43db2), [`73b2bca15`](https://github.com/navikt/aksel/commit/73b2bca156072c945c2fc4e4e849f50a00398eb6), [`d278060e5`](https://github.com/navikt/aksel/commit/d278060e59b17638cbda22dc194e89b01dc2113e)]:
- @navikt/ds-css@7.1.1
## 7.1.0
### Patch Changes
- Updated dependencies [[`9c1eba445`](https://github.com/navikt/aksel/commit/9c1eba44508f295cc6261ff96822b18557bd7ddc)]:
- @navikt/ds-css@7.1.0
## 7.0.1
### Patch Changes
- Updated dependencies [[`057bfe85b`](https://github.com/navikt/aksel/commit/057bfe85be772d7a483dac096982630922bdd736)]:
- @navikt/ds-css@7.0.1
## 7.0.0
### Patch Changes
- Updated dependencies [[`1c11a6a3b`](https://github.com/navikt/aksel/commit/1c11a6a3b95fe6d0f5015d3b073e05fe5912071b)]:
- @navikt/ds-css@7.0.0
## 6.17.0
### Patch Changes
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/aksel",
"version": "6.17.0",
"version": "7.2.1",
"description": "Aksel command line interface. Handles css-imports, codemods and more",
"author": "Aksel | NAV designsystem team",
"license": "MIT",
@@ -29,7 +29,7 @@
},
"homepage": "https://aksel.nav.no/grunnleggende/kode/kommandolinje",
"dependencies": {
"@navikt/ds-css": "6.17.0",
"@navikt/ds-css": "7.2.1",
"axios": "1.7.4",
"chalk": "4.1.0",
"clipboardy": "^2.3.0",
+1
View File
@@ -1,6 +1,7 @@
import { applyTransform } from "jscodeshift/dist/testUtils";
import fs from "node:fs";
import path from "node:path";
// eslint-disable-next-line import/default
import prettier from "prettier";
import { describe, expect, test } from "vitest";
+1 -1
View File
@@ -43,7 +43,7 @@ export function validateGit(options: any, program: Command) {
try {
clean = isGitClean.sync(process.cwd());
} catch (err: any) {
if (err && err.stderr && err.stderr.indexOf("Not a git repository") >= 0) {
if (err?.stderr && err.stderr.indexOf("Not a git repository") >= 0) {
clean = true;
}
}
+1 -1
View File
@@ -5,7 +5,7 @@ export async function getAllVersions() {
const npmPackageData = await axios.get(
`https://registry.npmjs.org/@navikt/ds-css`,
);
return Object.keys(npmPackageData.data["versions"]);
return Object.keys(npmPackageData.data.versions);
} catch (e) {
console.error(e);
return [];
+1 -1
View File
@@ -137,7 +137,7 @@ export async function cssImportsCommand() {
let foundComponents: string[] = [];
if (answers["autoscan"] === "yes") {
if (answers.autoscan === "yes") {
foundComponents = await new Promise((resolve) => {
exec(`node ${__dirname}/scan-code.js ${answers.scandir}`, (_, stdout) => {
resolve(
+42
View File
@@ -1,5 +1,47 @@
# @navikt/ds-css
## 7.2.1
### Patch Changes
- Combobox: Support PageUp/PageDown in dropdown list. ([#3158](https://github.com/navikt/aksel/pull/3158))
## 7.2.0
## 7.1.2
### Patch Changes
- List: Explicitly set list-style on ol to override reset-CSS ([#3202](https://github.com/navikt/aksel/pull/3202))
## 7.1.1
### Patch Changes
- List: Add indentation and remove overly verbose aria attributes ([#3184](https://github.com/navikt/aksel/pull/3184))
- Datepicker/Select: :lipstick: dim non-interactable icons when readonly is set. ([#3187](https://github.com/navikt/aksel/pull/3187))
- Combobox: :bug: implement missing readonly and disabled ([#3180](https://github.com/navikt/aksel/pull/3180))
## 7.1.0
### Patch Changes
- Accordion: Remove 'relative' positioning when focused. This resolves some issues where floating elements like popover ended up clipping. ([`9c1eba445`](https://github.com/navikt/aksel/commit/9c1eba44508f295cc6261ff96822b18557bd7ddc))
## 7.0.1
### Patch Changes
- List: :lipstick: make icons 24x24px large ([#3148](https://github.com/navikt/aksel/pull/3148))
## 7.0.0
### Patch Changes
- ErrorSummary: Focus heading instead of container for improved experience with screen reader. ([#3139](https://github.com/navikt/aksel/pull/3139))
## 6.17.0
## 6.16.3
-4
View File
@@ -2,10 +2,6 @@
--__ac-accordion-header-shadow-color: var(--ac-accordion-header-border, var(--a-border-divider));
}
.navds-accordion__item:focus-within {
position: relative;
}
/*************************
* Header *
*************************/
-1
View File
@@ -31,7 +31,6 @@
@media (forced-colors: active) {
.navds-copybutton {
background-color: ButtonFace;
border-color: ButtonText;
border: solid 1px ButtonText;
color: ButtonText;
}
+1
View File
@@ -281,6 +281,7 @@
/* Readonly */
.navds-date__field--readonly .navds-date__field-button {
cursor: default;
color: var(--a-gray-500);
}
.navds-date__caption-button {
+31
View File
@@ -20,6 +20,36 @@
--__ac-combobox-input-height: 1.5rem;
}
.navds-combobox--disabled {
opacity: 0.3;
}
.navds-combobox--disabled .navds-combobox__wrapper *:hover {
cursor: not-allowed;
}
.navds-combobox--disabled .navds-text-field__input {
border: 1px solid var(--a-border-default);
}
.navds-combobox--disabled .navds-combobox__selected-options {
pointer-events: none;
}
.navds-combobox--readonly {
pointer-events: none;
}
.navds-combobox--readonly .navds-combobox__button-toggle-list {
color: var(--a-gray-500);
}
.navds-combobox--readonly .navds-text-field__input,
.navds-combobox--readonly .navds-combobox__input {
background-color: var(--a-surface-subtle);
border-color: var(--a-border-subtle);
}
.navds-combobox__button-clear svg,
.navds-combobox__button-toggle-list svg,
.navds-combobox__list svg {
@@ -233,6 +263,7 @@
border-radius: var(--a-border-radius-medium);
background-color: var(--ac-combobox-list-bg, var(--a-surface-default));
color: var(--ac-combobox-list-text, var(--a-text-default));
overscroll-behavior: contain;
}
.navds-combobox__list--closed {
+8
View File
@@ -9,6 +9,14 @@
padding: var(--a-spacing-3);
}
.navds-error-summary__heading {
scroll-margin-top: var(--a-spacing-6);
}
.navds-error-summary--small .navds-error-summary__heading {
scroll-margin-top: var(--a-spacing-4);
}
.navds-error-summary__heading:focus {
outline: none;
}
+4
View File
@@ -109,3 +109,7 @@
border-color: var(--a-border-subtle);
cursor: default;
}
.navds-select--readonly .navds-select__chevron {
color: var(--a-gray-500);
}
-1
View File
@@ -10,7 +10,6 @@
@media (forced-colors: active) {
.navds-internalheader {
background-color: ButtonFace;
border-color: ButtonText;
border: solid 1px ButtonText;
color: ButtonText;
}
+60 -70
View File
@@ -4,91 +4,81 @@
margin-block: var(--a-spacing-4);
}
.navds-list--nested ul,
.navds-list--nested ol {
margin-block: var(--a-spacing-2);
}
.navds-list--small ul,
.navds-list--small ol {
margin-block: var(--a-spacing-3);
}
.navds-list li {
margin-block-end: var(--a-spacing-2);
}
.navds-list:last-child > ul > li:last-child,
.navds-list:last-child > ol > li:last-child {
margin-bottom: 0;
}
.navds-list ul .navds-list__item {
display: grid;
grid-template-columns: auto 1fr;
gap: var(--a-spacing-3);
padding-left: 0;
}
.navds-list ul .navds-list__item::marker {
content: none;
}
.navds-list ol .navds-list__item-marker--icon {
grid-column: 1 / 2;
display: flex;
}
.navds-list .navds-list__item-marker--bullet {
display: flex;
align-items: center;
height: var(--a-font-line-height-xlarge);
grid-column: 1 / 2;
color: var(--ac-list-marker-ul-color, var(--ac-list-marker-color, var(--a-icon-default)));
}
.navds-list--small .navds-list__item-marker--bullet {
height: var(--a-font-line-height-large);
}
.navds-list__item-marker--icon {
color: var(--ac-list-marker-icon-color, var(--ac-list-marker-color, var(--a-icon-default)));
display: flex;
align-items: center;
height: var(--a-font-line-height-xlarge);
padding-block-end: 1px;
}
.navds-list--small .navds-list__item-marker--icon {
height: var(--a-font-line-height-large);
}
.navds-list__item-marker--icon svg {
flex-shrink: 0;
}
.navds-list ul .navds-list__item-content {
grid-column: 2 / 3;
.navds-list .navds-list :where(ul, ol) {
margin-block: var(--a-spacing-2) 0;
}
.navds-list ol {
padding-left: var(--a-spacing-2);
list-style: decimal;
list-style: decimal; /* This is the default value, but some frameworks have `ol,ul { list-style:none }` */
padding-left: 1.7rem;
}
.navds-list ol li {
padding-left: var(--a-spacing-1);
margin-left: var(--a-spacing-2);
.navds-list ol > .navds-list__item {
padding-left: 0.3rem;
}
/* SAFARI HACK START */
/* stylelint-disable selector-type-no-unknown */
_::-webkit-full-page-media,
_:future,
:root .navds-list ol {
padding-left: 2.1rem;
}
_::-webkit-full-page-media,
_:future,
:root .navds-list ol .navds-list__item {
padding-left: 0;
}
/* SAFARI HACK END */
/* stylelint-enable selector-type-no-unknown */
.navds-list__item {
margin-block-end: var(--a-spacing-2);
}
.navds-list__item:last-child {
margin-block-end: 0;
}
.navds-list ul > .navds-list__item {
display: grid;
grid-template-columns: auto 1fr;
gap: var(--a-spacing-2);
}
.navds-list ol li::marker {
font-weight: var(--a-font-weight-bold);
font-size: var(--a-font-size-large);
color: var(--ac-list-marker-ol-color, var(--ac-list-marker-color, var(--a-icon-default)));
line-height: var(--a-font-line-height-xlarge);
}
.navds-list--small ol li::marker {
font-size: var(--a-font-size-small);
line-height: var(--a-font-line-height-large);
.navds-list__item-marker {
width: 1.5rem;
}
.navds-list ul > li > .navds-list__item-marker {
display: flex;
align-items: center;
height: var(--a-font-line-height-xlarge);
}
.navds-list--small ul > li > .navds-list__item-marker {
height: var(--a-font-line-height-large);
}
.navds-list__item-marker--bullet {
padding-left: 0.8rem;
color: var(--ac-list-marker-ul-color, var(--ac-list-marker-color, var(--a-icon-default)));
}
.navds-list__item-marker--icon {
font-size: 1.5rem;
color: var(--ac-list-marker-icon-color, var(--ac-list-marker-color, var(--a-icon-default)));
}
+3 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-css",
"version": "6.17.0",
"version": "7.2.1",
"description": "CSS for NAV Designsystem",
"author": "Aksel | NAV designsystem team",
"keywords": [
@@ -27,7 +27,8 @@
"css:get-version": "node config/get-version.js"
},
"devDependencies": {
"@navikt/ds-tokens": "^6.17.0",
"@navikt/ds-tokens": "^7.2.1",
"autoprefixer": "^10.4.20",
"cssnano": "6.0.0",
"fast-glob": "3.2.11",
"lodash": "4.17.21",
-1
View File
@@ -19,7 +19,6 @@
@media (forced-colors: active) {
.navds-read-more__button {
background-color: ButtonFace;
border-color: ButtonText;
border: solid 1px ButtonText;
color: ButtonText;
}
+90
View File
@@ -1,5 +1,95 @@
# @navikt/ds-react
## 7.2.1
### Patch Changes
- Combobox: Disable autocomple in Firefox on Android to prevent bug ([#3201](https://github.com/navikt/aksel/pull/3201))
- Combobox: Support PageUp/PageDown in dropdown list. ([#3158](https://github.com/navikt/aksel/pull/3158))
- Updated dependencies []:
- @navikt/ds-tokens@7.2.1
- @navikt/aksel-icons@7.2.1
## 7.2.0
### Minor Changes
- FileUpload: :boom: Remove UNSAFE-prefix ([#3205](https://github.com/navikt/aksel/pull/3205))
- List: :sparkles: New size 'large' ([#3207](https://github.com/navikt/aksel/pull/3207))
### Patch Changes
- Performance: :zap: Optimized memoization for rerendring in some components. ([#3197](https://github.com/navikt/aksel/pull/3197))
- Updated dependencies []:
- @navikt/ds-tokens@7.2.0
- @navikt/aksel-icons@7.2.0
## 7.1.2
### Patch Changes
- Updated dependencies []:
- @navikt/ds-tokens@7.1.2
- @navikt/aksel-icons@7.1.2
## 7.1.1
### Patch Changes
- List: Add indentation and remove overly verbose aria attributes ([#3184](https://github.com/navikt/aksel/pull/3184))
- Combobox: :bug: implement missing readonly and disabled ([#3180](https://github.com/navikt/aksel/pull/3180))
- Updated dependencies []:
- @navikt/ds-tokens@7.1.1
- @navikt/aksel-icons@7.1.1
## 7.1.0
### Minor Changes
- Pagination: :lipstick: Updated font-weight to 600 and marked 'page'-prop on 'Item' as deprecated. ([#3164](https://github.com/navikt/aksel/pull/3164))
### Patch Changes
- Combobox: :label: Better typing for maxSelected prop ([#3169](https://github.com/navikt/aksel/pull/3169))
- ErrorSummary: Remove aria-attributes. ([#3171](https://github.com/navikt/aksel/pull/3171))
- Updated dependencies []:
- @navikt/ds-tokens@7.1.0
- @navikt/aksel-icons@7.1.0
## 7.0.1
### Patch Changes
- Combobox: Fix issue with whitespace in the ID of options with multiple spaces ([#3162](https://github.com/navikt/aksel/pull/3162))
- Updated dependencies []:
- @navikt/ds-tokens@7.0.1
- @navikt/aksel-icons@7.0.1
## 7.0.0
### Major Changes
- ErrorSummary: Added fallback text for `heading`. ([#3139](https://github.com/navikt/aksel/pull/3139))
- Tooltip: :boom: Updated labeling of items inside Tooltip. [See migration guide for how to update](https://aksel.nav.no/grunnleggende/kode/migrering#3b5cf05fd100). ([#3139](https://github.com/navikt/aksel/pull/3139))
### Patch Changes
- ErrorSummary: Focus heading instead of container for improved experience with screen reader. ([#3139](https://github.com/navikt/aksel/pull/3139))
- Updated dependencies [[`1c11a6a3b`](https://github.com/navikt/aksel/commit/1c11a6a3b95fe6d0f5015d3b073e05fe5912071b)]:
- @navikt/aksel-icons@7.0.0
- @navikt/ds-tokens@7.0.0
## 6.17.0
### Minor Changes
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-react",
"version": "6.17.0",
"version": "7.2.1",
"description": "React components from the Norwegian Labour and Welfare Administration.",
"author": "Aksel, a team part of the Norwegian Labour and Welfare Administration.",
"license": "MIT",
@@ -583,7 +583,7 @@
"./package.json": "./package.json"
},
"scripts": {
"docgen": "yarn ts-node ../../../scripts/docgen.ts",
"docgen": "yarn tsx ../../../scripts/docgen.ts",
"write-packagejson": "echo '{\"type\": \"module\"}' > esm/package.json",
"clean": "rimraf cjs esm",
"build": "concurrently \"tsc -p tsconfig.build.json\" \"tsc -p tsconfig.esm.json && tsc-alias -p tsconfig.esm.json && yarn write-packagejson\" ",
@@ -594,8 +594,8 @@
"dependencies": {
"@floating-ui/react": "0.25.4",
"@floating-ui/react-dom": "^2.0.9",
"@navikt/aksel-icons": "^6.17.0",
"@navikt/ds-tokens": "^6.17.0",
"@navikt/aksel-icons": "^7.2.1",
"@navikt/ds-tokens": "^7.2.1",
"clsx": "^2.1.0",
"date-fns": "^3.0.0",
"react-day-picker": "8.10.0"
@@ -614,8 +614,8 @@
"react-router-dom": "^6.3.0",
"rimraf": "6.0.1",
"swr": "^1.1.2",
"ts-node": "^10.9.1",
"tsc-alias": "1.8.8",
"tsx": "^4.19.1",
"typescript": "^5.1.6",
"vitest": "^1.2.2"
},
+4 -4
View File
@@ -58,7 +58,7 @@ export const Size: Story = {
render: () => (
<VStack gap="4">
{SIZES.map((size) => (
<>
<React.Fragment key={size}>
<h3>{size}</h3>
<Chat
avatar="ON"
@@ -75,7 +75,7 @@ export const Size: Story = {
laboris labore nisi ut.
</Chat.Bubble>
</Chat>
</>
</React.Fragment>
))}
</VStack>
),
@@ -85,7 +85,7 @@ export const Variants: Story = {
render: () => (
<VStack gap="4">
{VARIANTS.map((variant) => (
<>
<React.Fragment key={variant}>
<h3>{variant}</h3>
<Chat
avatar="NAV"
@@ -97,7 +97,7 @@ export const Variants: Story = {
Aute minim nisi sunt mollit duis sunt nulla minim non proident.
</Chat.Bubble>
</Chat>
</>
</React.Fragment>
))}
</VStack>
),
@@ -73,40 +73,35 @@ export const Default: StoryObj<DefaultStoryProps> = {
locale={props.locale}
disableWeekends={props.disableWeekends}
>
{!props.standalone && (
<>
{props.inputfield && props.mode !== "multiple" ? (
<>
{props.mode === "range" ? (
<div style={{ display: "flex", gap: "1rem" }}>
<DatePicker.Input
label="Fra"
size={props?.size}
{...rangeCtx.fromInputProps}
/>
<DatePicker.Input
label="Til"
size={props?.size}
{...rangeCtx.toInputProps}
/>
</div>
) : (
<>
<DatePicker.Input
label="Velg dato"
size={props?.size}
{...singleCtx.inputProps}
/>
</>
)}
</>
) : (
<Button onClick={() => setOpen((x) => !x)}>
Åpne datovelger
</Button>
)}
</>
)}
{!props.standalone &&
(props.inputfield && props.mode !== "multiple" ? (
<>
{props.mode === "range" ? (
<div style={{ display: "flex", gap: "1rem" }}>
<DatePicker.Input
label="Fra"
size={props?.size}
{...rangeCtx.fromInputProps}
/>
<DatePicker.Input
label="Til"
size={props?.size}
{...rangeCtx.toInputProps}
/>
</div>
) : (
<DatePicker.Input
label="Velg dato"
size={props?.size}
{...singleCtx.inputProps}
/>
)}
</>
) : (
<Button onClick={() => setOpen((x) => !x)}>
Åpne datovelger
</Button>
))}
</Comp>
</div>
);
@@ -19,7 +19,7 @@ const App = () => {
};
describe("Render datepicker", () => {
// eslint-disable-next-line vitest/expect-expect
// eslint-disable-next-line @vitest/expect-expect
test("Should not crash when e.target is window", async () => {
render(<App />);
@@ -4,29 +4,29 @@ import { describe, expect, test } from "vitest";
import { isValidDate, parseDate } from "..";
const check = (inp: string) =>
// eslint-disable-next-line vitest/valid-expect
// eslint-disable-next-line @vitest/valid-expect
expect(isValidDate(parseDate(inp, new Date(), nb, "date", false)));
const checkTwoDigit = (inp: string) =>
// eslint-disable-next-line vitest/valid-expect
// eslint-disable-next-line @vitest/valid-expect
expect(isValidDate(parseDate(inp, new Date(), nb, "date", true)));
const parse = (inp: string) => parseDate(inp, new Date(), nb, "date", false);
describe("Parse date-inputs with 4-digit years", () => {
// eslint-disable-next-line vitest/expect-expect
// eslint-disable-next-line @vitest/expect-expect
test("No spaces", () => {
check("11052022").toBeTruthy();
check("15052022").toBeTruthy();
});
// eslint-disable-next-line vitest/expect-expect
// eslint-disable-next-line @vitest/expect-expect
test(". divider", () => {
check("1.5.2022").toBeTruthy();
check("11.05.2022").toBeTruthy();
});
// eslint-disable-next-line vitest/expect-expect
// eslint-disable-next-line @vitest/expect-expect
test("/ divider", () => {
check("1/5/2022").toBeTruthy();
check("10/5/2022").toBeTruthy();
@@ -34,7 +34,7 @@ describe("Parse date-inputs with 4-digit years", () => {
check("10/05/2022").toBeTruthy();
});
// eslint-disable-next-line vitest/expect-expect
// eslint-disable-next-line @vitest/expect-expect
test("- divider", () => {
check("1-5-2022").toBeTruthy();
check("10-5-2022").toBeTruthy();
@@ -44,19 +44,19 @@ describe("Parse date-inputs with 4-digit years", () => {
});
describe("Parse date-inputs with 2-digit years", () => {
// eslint-disable-next-line vitest/expect-expect
// eslint-disable-next-line @vitest/expect-expect
test("No spaces", () => {
checkTwoDigit("110522").toBeTruthy();
checkTwoDigit("150522").toBeTruthy();
});
// eslint-disable-next-line vitest/expect-expect
// eslint-disable-next-line @vitest/expect-expect
test(". divider", () => {
checkTwoDigit("1.5.22").toBeTruthy();
checkTwoDigit("11.05.22").toBeTruthy();
});
// eslint-disable-next-line vitest/expect-expect
// eslint-disable-next-line @vitest/expect-expect
test("/ divider", () => {
checkTwoDigit("1/5/22").toBeTruthy();
checkTwoDigit("10/5/22").toBeTruthy();
@@ -64,7 +64,7 @@ describe("Parse date-inputs with 2-digit years", () => {
checkTwoDigit("10/05/22").toBeTruthy();
});
// eslint-disable-next-line vitest/expect-expect
// eslint-disable-next-line @vitest/expect-expect
test("- divider", () => {
checkTwoDigit("1-5-22").toBeTruthy();
checkTwoDigit("10-5-22").toBeTruthy();
@@ -72,14 +72,14 @@ describe("Parse date-inputs with 2-digit years", () => {
checkTwoDigit("10-05-22").toBeTruthy();
});
// eslint-disable-next-line vitest/expect-expect
// eslint-disable-next-line @vitest/expect-expect
test("Dissallow 1 and 3 digit years", () => {
checkTwoDigit("11052").toBeFalsy();
checkTwoDigit("1105222").toBeFalsy();
checkTwoDigit("1105999").toBeFalsy();
});
// eslint-disable-next-line vitest/expect-expect
// eslint-disable-next-line @vitest/expect-expect
test("Dissallow date before year 1000", () => {
checkTwoDigit("11050999").toBeFalsy();
checkTwoDigit("11050010").toBeFalsy();
@@ -82,7 +82,7 @@ export const Menu = forwardRef<HTMLDivElement, DropdownMenuProps>(
open={isOpen}
onClose={() => {
handleToggle(false);
onClose && onClose();
onClose?.();
}}
/>
);
@@ -65,33 +65,29 @@ const Content = () => (
type DefaultStoryProps = ExpansionCardProps & { description: boolean };
type DefaultStory = StoryFn<DefaultStoryProps>;
export const Default: DefaultStory = (props: DefaultStoryProps) => {
return (
<ExpansionCard
{...props}
open={props.open || undefined}
aria-label="default-demo"
>
<ExpansionCard.Header>
<ExpansionCard.Title>Arbeidstakere</ExpansionCard.Title>
{props.description && (
<ExpansionCard.Description>
For at yrkesskadedekningen skal gjelde, er det som hovedregel krav
til tid, sted og arbeidsoppgaver
</ExpansionCard.Description>
)}
</ExpansionCard.Header>
<Content />
</ExpansionCard>
);
};
export const Default: DefaultStory = ({
description,
...rest
}: DefaultStoryProps) => (
<ExpansionCard {...rest} aria-label="default-demo">
<ExpansionCard.Header>
<ExpansionCard.Title>Arbeidstakere</ExpansionCard.Title>
{description && (
<ExpansionCard.Description>
For at yrkesskadedekningen skal gjelde, er det som hovedregel krav til
tid, sted og arbeidsoppgaver
</ExpansionCard.Description>
)}
</ExpansionCard.Header>
<Content />
</ExpansionCard>
);
Default.args = {
open: false,
size: "medium",
description: false,
};
Default.argTypes = {
size: { control: "radio", options: ["medium", "small"] },
open: { control: "boolean" },
};
export const Description = () => (
@@ -44,8 +44,8 @@ const useCheckbox = (props: CheckboxProps) => {
if (readOnly) {
return;
}
props.onChange && props.onChange(e);
checkboxGroup && checkboxGroup.toggleValue(props.value);
props.onChange?.(e);
checkboxGroup?.toggleValue(props.value);
},
onClick: (e) => {
if (readOnly) {
@@ -1,6 +1,7 @@
import cl from "clsx";
import React, { forwardRef } from "react";
import { BodyShort, ErrorMessage, Label } from "../../typography";
import { ReadOnlyIcon } from "../ReadOnlyIcon";
import ComboboxWrapper from "./ComboboxWrapper";
import FilteredOptions from "./FilteredOptions/FilteredOptions";
import { useFilteredOptionsContext } from "./FilteredOptions/filteredOptionsContext";
@@ -27,6 +28,7 @@ export const Combobox = forwardRef<
inputProps,
showErrorMsg,
size = "medium",
readOnly,
} = useInputContext();
return (
@@ -44,6 +46,7 @@ export const Combobox = forwardRef<
"navds-sr-only": hideLabel,
})}
>
<ReadOnlyIcon nativeReadOnly={false} readOnly={readOnly} />
{label}
</Label>
{!!description && (
@@ -36,6 +36,7 @@ const ComboboxProvider = forwardRef<HTMLInputElement, ComboboxProps>(
children,
defaultValue,
disabled,
readOnly,
error,
errorId,
filteredOptions: externalFilteredOptions,
@@ -50,19 +51,28 @@ const ComboboxProvider = forwardRef<HTMLInputElement, ComboboxProps>(
value,
onChange,
onClear,
shouldAutocomplete,
shouldAutocomplete: externalShouldAutocomplete,
size,
...rest
} = props;
const options = mapToComboboxOptionArray(externalOptions) || [];
const filteredOptions = mapToComboboxOptionArray(externalFilteredOptions);
const selectedOptions = mapToComboboxOptionArray(externalSelectedOptions);
const userAgent =
typeof navigator === "undefined" ? "" : navigator.userAgent;
const isFirefoxOnAndroid =
userAgent.includes("Android") && userAgent.includes("Firefox/");
const shouldAutocomplete =
!isFirefoxOnAndroid && externalShouldAutocomplete;
return (
<InputContextProvider
value={{
defaultValue,
description: rest.description,
disabled,
readOnly,
error,
errorId,
id,
@@ -9,6 +9,7 @@ type ComboboxWrapperProps = {
inputProps: {
disabled?: boolean;
};
readOnly?: boolean;
inputSize: string;
toggleIsListOpen: (isListOpen: boolean) => void;
};
@@ -21,7 +22,7 @@ const ComboboxWrapper = ({
inputSize,
toggleIsListOpen,
}: ComboboxWrapperProps) => {
const { toggleOpenButtonRef, clearInput } = useInputContext();
const { toggleOpenButtonRef, clearInput, readOnly } = useInputContext();
const wrapperRef = useRef<HTMLDivElement | null>(null);
const [hasFocusWithin, setHasFocusWithin] = useState(false);
@@ -55,6 +56,8 @@ const ComboboxWrapper = ({
"navds-combobox--error": hasError,
"navds-combobox--disabled": !!inputProps.disabled,
"navds-combobox--focused": hasFocusWithin,
"navds-combobox--readonly": readOnly,
"navds-form-field--readonly": readOnly,
},
)}
onFocus={onFocusInsideWrapper}
@@ -54,6 +54,7 @@ const FilteredOptions = () => {
)}
{shouldRenderFilteredOptionsList && (
/* biome-ignore lint/a11y/useFocusableInteractive: Interaction is not handeled by listbox itself. */
<ul
ref={setFilteredOptionsRef}
role="listbox"
@@ -0,0 +1,18 @@
import { describe } from "vitest";
import filteredOptionsUtil from "./filtered-options-util";
describe("filtered options util", () => {
describe("getOptionId", () => {
it("should return the correct id", () => {
expect(filteredOptionsUtil.getOptionId("combobox", "option")).toBe(
"combobox-option-option",
);
});
it("should return the correct id with spaces", () => {
expect(
filteredOptionsUtil.getOptionId("combobox", "option with spaces"),
).toBe("combobox-option-option-with-spaces");
});
});
});
@@ -19,9 +19,7 @@ const getFilteredOptionsId = (comboboxId: string) =>
`${comboboxId}-filtered-options`;
const getOptionId = (comboboxId: string, option: string) =>
`${comboboxId.toLocaleLowerCase()}-option-${option
.replace(" ", "-")
.toLocaleLowerCase()}`;
`${comboboxId}-option-${option}`.replace(/\s/g, "-").toLocaleLowerCase();
const getAddNewOptionId = (comboboxId: string) =>
`${comboboxId}-combobox-new-option`;
@@ -58,7 +58,8 @@ const FilteredOptionsProvider = ({
useState<HTMLUListElement | null>(null);
const virtualFocus = useVirtualFocus(filteredOptionsRef);
const {
inputProps: { "aria-describedby": partialAriaDescribedBy, id },
inputProps: { "aria-describedby": partialAriaDescribedBy, id, disabled },
readOnly,
value,
searchTerm,
setValue,
@@ -136,7 +137,10 @@ const FilteredOptionsProvider = ({
const toggleIsListOpen = useCallback(
(newState?: boolean) => {
virtualFocus.moveFocusToTop();
if (disabled || readOnly) {
return;
}
virtualFocus.resetFocus();
if (newState ?? !isInternalListOpen) {
setHideCaret(!!maxSelected?.isLimitReached);
}
@@ -147,6 +151,8 @@ const FilteredOptionsProvider = ({
maxSelected?.isLimitReached,
isInternalListOpen,
setHideCaret,
disabled,
readOnly,
],
);
@@ -1,4 +1,4 @@
import { useState } from "react";
import { useEffect, useState } from "react";
export type VirtualFocusType = {
activeElement: HTMLElement | undefined;
@@ -10,6 +10,9 @@ export type VirtualFocusType = {
moveFocusToElement: (id: string) => void;
moveFocusToTop: () => void;
moveFocusToBottom: () => void;
moveFocusUpBy: (numberOfElements: number) => void;
moveFocusDownBy: (numberOfElements: number) => void;
resetFocus: () => void;
};
const useVirtualFocus = (
@@ -40,11 +43,6 @@ const useVirtualFocus = (
: false;
};
const _moveFocusAndScrollTo = (_element?: HTMLElement) => {
setActiveElement(_element);
_element?.scrollIntoView?.({ block: "nearest" });
};
const moveFocusUp = () => {
if (!activeElement) {
return;
@@ -55,14 +53,14 @@ const useVirtualFocus = (
if (_currentIndex === 0) {
setActiveElement(undefined);
} else {
_moveFocusAndScrollTo(elementAbove);
setActiveElement(elementAbove);
}
};
const moveFocusDown = () => {
const elementsAbleToReceiveFocus = getElementsAbleToReceiveFocus();
if (!activeElement) {
_moveFocusAndScrollTo(elementsAbleToReceiveFocus[0]);
setActiveElement(elementsAbleToReceiveFocus[0]);
return;
}
const _currentIndex = elementsAbleToReceiveFocus.indexOf(activeElement);
@@ -70,13 +68,17 @@ const useVirtualFocus = (
return;
}
_moveFocusAndScrollTo(elementsAbleToReceiveFocus[_currentIndex + 1]);
setActiveElement(elementsAbleToReceiveFocus[_currentIndex + 1]);
};
const moveFocusToTop = () => _moveFocusAndScrollTo(undefined);
const resetFocus = () => setActiveElement(undefined);
const moveFocusToTop = () => {
const elementsAbleToReceiveFocus = getElementsAbleToReceiveFocus();
setActiveElement(elementsAbleToReceiveFocus[0]);
};
const moveFocusToBottom = () => {
const elementsAbleToReceiveFocus = getElementsAbleToReceiveFocus();
return _moveFocusAndScrollTo(
setActiveElement(
elementsAbleToReceiveFocus[elementsAbleToReceiveFocus.length - 1],
);
};
@@ -89,6 +91,32 @@ const useVirtualFocus = (
}
};
const moveFocusUpBy = (numberOfElements: number) => {
if (!activeElement) {
return;
}
const elementsAbleToReceiveFocus = getElementsAbleToReceiveFocus();
const currentIndex = elementsAbleToReceiveFocus.indexOf(activeElement);
const newIndex = Math.max(currentIndex - numberOfElements, 0);
setActiveElement(elementsAbleToReceiveFocus[newIndex]);
};
const moveFocusDownBy = (numberOfElements: number) => {
const elementsAbleToReceiveFocus = getElementsAbleToReceiveFocus();
const currentIndex = activeElement
? elementsAbleToReceiveFocus.indexOf(activeElement)
: -1;
const newIndex = Math.min(
currentIndex + numberOfElements,
elementsAbleToReceiveFocus.length - 1,
);
setActiveElement(elementsAbleToReceiveFocus[newIndex]);
};
useEffect(() => {
activeElement?.scrollIntoView?.({ block: "nearest" });
}, [activeElement]);
return {
activeElement,
getElementById,
@@ -99,6 +127,9 @@ const useVirtualFocus = (
moveFocusToElement,
moveFocusToTop,
moveFocusToBottom,
moveFocusUpBy,
moveFocusDownBy,
resetFocus,
};
};
@@ -32,6 +32,7 @@ interface Props {
defaultValue: ComboboxProps["defaultValue"];
description: ComboboxProps["description"];
disabled: ComboboxProps["disabled"];
readOnly: ComboboxProps["readOnly"];
error: ComboboxProps["error"];
errorId: ComboboxProps["errorId"];
id: ComboboxProps["id"];
@@ -48,6 +49,7 @@ const InputProvider = ({ children, value: props }: Props) => {
defaultValue = "",
description,
disabled,
readOnly,
error,
errorId,
id: externalId,
@@ -61,6 +63,7 @@ const InputProvider = ({ children, value: props }: Props) => {
{
description,
disabled,
readOnly,
error,
errorId,
id: externalId,
@@ -96,7 +99,7 @@ const InputProvider = ({ children, value: props }: Props) => {
setInternalValue("");
setSearchTerm("");
},
[externalOnChange, onClear, setInternalValue],
[externalOnChange, onClear],
);
const focusInput = useCallback(() => {
@@ -49,6 +49,7 @@ const Input = forwardRef<HTMLInputElement, InputProps>(
setValue,
hideCaret,
setHideCaret,
readOnly,
} = useInputContext();
const {
selectedOptions,
@@ -133,14 +134,6 @@ const Input = forwardRef<HTMLInputElement, InputProps>(
case "Accept":
onEnter(e);
break;
case "Home":
toggleIsListOpen(false);
virtualFocus.moveFocusToTop();
break;
case "End":
toggleIsListOpen(true);
virtualFocus.moveFocusToBottom();
break;
default:
break;
}
@@ -149,6 +142,9 @@ const Input = forwardRef<HTMLInputElement, InputProps>(
const handleKeyDown = useCallback(
(e: React.KeyboardEvent<HTMLInputElement>) => {
setIsMouseLastUsedInputDevice(false);
if (readOnly) {
return;
}
if (e.key === "Backspace") {
if (value === "" && shouldShowSelectedOptions) {
const lastSelectedOption =
@@ -198,6 +194,24 @@ const Input = forwardRef<HTMLInputElement, InputProps>(
}
virtualFocus.moveFocusUp();
}
} else if (e.key === "Home") {
e.preventDefault();
virtualFocus.moveFocusToTop();
} else if (e.key === "End") {
e.preventDefault();
if (virtualFocus.activeElement === null || !isListOpen) {
toggleIsListOpen(true);
}
virtualFocus.moveFocusToBottom();
} else if (e.key === "PageUp") {
e.preventDefault();
virtualFocus.moveFocusUpBy(6);
} else if (e.key === "PageDown") {
e.preventDefault();
if (virtualFocus.activeElement === null || !isListOpen) {
toggleIsListOpen(true);
}
virtualFocus.moveFocusDownBy(6);
}
},
[
@@ -214,6 +228,7 @@ const Input = forwardRef<HTMLInputElement, InputProps>(
setValue,
searchTerm,
shouldShowSelectedOptions,
readOnly,
],
);
@@ -225,10 +240,9 @@ const Input = forwardRef<HTMLInputElement, InputProps>(
} else if (filteredOptions.length === 0) {
toggleIsListOpen(false);
}
virtualFocus.moveFocusToTop();
onChange(newValue);
},
[filteredOptions.length, virtualFocus, onChange, toggleIsListOpen],
[filteredOptions.length, onChange, toggleIsListOpen],
);
return (
@@ -262,6 +276,7 @@ const Input = forwardRef<HTMLInputElement, InputProps>(
aria-activedescendant={activeDecendantId}
aria-describedby={ariaDescribedBy}
aria-invalid={inputProps["aria-invalid"]}
readOnly={readOnly}
/>
);
},
@@ -45,6 +45,7 @@ export const InputController = forwardRef<
size = "medium",
inputRef,
toggleOpenButtonRef,
readOnly,
} = useInputContext();
const { activeDecendantId } = useFilteredOptionsContext();
@@ -65,6 +66,7 @@ export const InputController = forwardRef<
id={inputProps.id}
ref={mergedInputRef}
inputClassName={inputClassName}
readOnly={readOnly}
{...rest}
/>
) : (
@@ -74,6 +76,7 @@ export const InputController = forwardRef<
ref={mergedInputRef}
inputClassName={inputClassName}
shouldShowSelectedOptions={shouldShowSelectedOptions}
readOnly={readOnly}
{...rest}
/>
</SelectedOptions>
@@ -12,7 +12,7 @@ interface SelectedOptionsProps {
const Option = ({ option }: { option: ComboboxOption }) => {
const { isMultiSelect, removeSelectedOption } = useSelectedOptionsContext();
const { focusInput } = useInputContext();
const { focusInput, readOnly, inputProps } = useInputContext();
const onClick = (e) => {
e.stopPropagation();
@@ -28,7 +28,13 @@ const Option = ({ option }: { option: ComboboxOption }) => {
);
}
return <Chips.Removable onClick={onClick}>{option.label}</Chips.Removable>;
return readOnly || inputProps.disabled ? (
<Chips.Toggle variant="neutral" checkmark={false} as="div">
{option.label}
</Chips.Toggle>
) : (
<Chips.Removable onClick={onClick}>{option.label}</Chips.Removable>
);
};
const SelectedOptions: React.FC<SelectedOptionsProps> = ({
@@ -4,7 +4,7 @@ import { usePrevious } from "../../../util/hooks";
import { useInputContext } from "../Input/Input.context";
import { isInList } from "../combobox-utils";
import { useComboboxCustomOptions } from "../customOptionsContext";
import { ComboboxOption, ComboboxProps, MaxSelected } from "../types";
import { ComboboxOption, ComboboxProps } from "../types";
type SelectedOptionsContextValue = {
addSelectedOption: (option: ComboboxOption) => void;
@@ -12,7 +12,7 @@ type SelectedOptionsContextValue = {
removeSelectedOption: (option: ComboboxOption) => void;
prevSelectedOptions?: ComboboxOption[];
selectedOptions: ComboboxOption[];
maxSelected?: MaxSelected & { isLimitReached: boolean };
maxSelected?: ComboboxProps["maxSelected"] & { isLimitReached: boolean };
setSelectedOptions: (any) => void;
toggleOption: (
option: ComboboxOption,
@@ -105,9 +105,10 @@ const SelectedOptionsProvider = ({
(!!maxSelected?.limit && selectedOptions.length >= maxSelected.limit) ||
(!isMultiSelect && selectedOptions.length > 0);
// biome-ignore lint/correctness/useExhaustiveDependencies: We explicitly want to run this effect when selectedOptions changes to match the view with the selected options.
useEffect(() => {
setHideCaret(isLimitReached);
}, [selectedOptions, setHideCaret, isLimitReached]);
}, [isLimitReached, selectedOptions, setHideCaret]);
const toggleOption = useCallback(
(
@@ -291,4 +291,40 @@ describe("Render combobox", () => {
);
});
});
describe("has keyboard navigation", () => {
test("for PageDown and PageUp", async () => {
render(<App options={options} />);
const combobox = screen.getByRole("combobox", {
name: "Hva er dine favorittfrukter?",
});
const pressKey = async (key: string) => {
await act(async () => {
await userEvent.keyboard(`{${key}}`);
});
};
const hasVirtualFocus = (option: string) =>
expect(combobox.getAttribute("aria-activedescendant")).toBe(
screen.getByRole("option", { name: option }).id,
);
await act(async () => {
await userEvent.click(combobox);
});
await pressKey("ArrowDown");
hasVirtualFocus("apple");
await pressKey("PageDown");
hasVirtualFocus("mango");
await pressKey("PageDown");
hasVirtualFocus("watermelon");
await pressKey("PageUp");
hasVirtualFocus("mango");
await pressKey("PageUp");
hasVirtualFocus("apple");
});
});
});
@@ -7,7 +7,7 @@ import { VStack } from "../../layout/stack";
import { Modal } from "../../modal";
import { BodyLong } from "../../typography";
import { TextField } from "../textfield";
import { UNSAFE_Combobox } from "./index";
import { ComboboxProps, UNSAFE_Combobox } from "./index";
export default {
title: "ds-react/Combobox",
@@ -38,14 +38,16 @@ const options = [
"grapefruit",
];
export const Default: StoryFunction = (props) => (
export const Default: StoryFn<ComboboxProps & { maxSelected?: number }> = ({
maxSelected,
...rest
}) => (
<UNSAFE_Combobox
{...props}
maxSelected={{ limit: Number(props.maxSelected) }}
{...rest}
maxSelected={maxSelected && { limit: maxSelected }}
id="combobox"
/>
);
Default.args = {
options,
label: "Hva er din favorittfrukt?",
@@ -65,6 +67,9 @@ Default.argTypes = {
disabled: {
control: { type: "boolean" },
},
readOnly: {
control: { type: "boolean" },
},
isListOpen: {
control: { type: "boolean" },
},
@@ -482,12 +487,50 @@ export const InModal: StoryFn = () => {
};
export const Disabled: StoryFn = () => {
const selectedOptionsMultiple = ["napoleonskake", "donut"];
const selectedOptionsSingle = ["pushups"];
return (
<UNSAFE_Combobox
options={options}
label="Hva er dine favorittfrukter?"
disabled
/>
<VStack gap="2">
<UNSAFE_Combobox
options={options}
label="Hva er dine favorittfrukter?"
description="Bare de fruktene som du spiser minst 5 av om dagen teller vi som en favorittfrukt."
selectedOptions={selectedOptionsMultiple}
isMultiSelect
disabled
/>
<UNSAFE_Combobox
options={options}
label="Hva er din favoritthobby?"
description="Her snakker vi ting du bruker minst én time på hver dag."
selectedOptions={selectedOptionsSingle}
disabled
/>
</VStack>
);
};
export const Readonly: StoryFn = () => {
const selectedOptionsMultiple = ["napoleonskake", "donut"];
const selectedOptionsSingle = ["pushups"];
return (
<VStack gap="2">
<UNSAFE_Combobox
options={options}
label="Hva er dine favorittfrukter?"
description="Bare de fruktene som du spiser minst 5 av om dagen teller vi som en favorittfrukt."
selectedOptions={selectedOptionsMultiple}
isMultiSelect
readOnly
/>
<UNSAFE_Combobox
options={options}
label="Hva er din favoritthobby?"
description="Her snakker vi ting du bruker minst én time på hver dag."
selectedOptions={selectedOptionsSingle}
readOnly
/>
</VStack>
);
};
@@ -523,6 +566,8 @@ export const Chromatic: StoryFn = () => {
<WithError />
<H2>Disabled</H2>
<Disabled />
<H2>Readonly</H2>
<Readonly />
</VStack>
);
};
@@ -35,7 +35,7 @@ const CustomOptionsProvider = ({
);
focusInput();
},
[focusInput, setCustomOptions],
[focusInput],
);
const addCustomOption = useCallback(
@@ -47,7 +47,7 @@ const CustomOptionsProvider = ({
}
focusInput();
},
[focusInput, isMultiSelect, setCustomOptions],
[focusInput, isMultiSelect],
);
const customOptionsState = {
+10 -12
View File
@@ -16,17 +16,6 @@ export type ComboboxOption = {
value: string;
};
export type MaxSelected = {
/**
* The limit for maximum selected options
*/
limit: number;
/**
* Override the message to display when the limit for maximum selected options has been reached
*/
message?: string;
};
export interface ComboboxProps
extends FormFieldProps,
Omit<
@@ -135,7 +124,16 @@ export interface ComboboxProps
/**
* Options for the maximum number of selected options.
*/
maxSelected?: MaxSelected;
maxSelected?: {
/**
* The limit for maximum selected options
*/
limit: number;
/**
* Override the message to display when the limit for maximum selected options has been reached
*/
message?: string;
};
/**
* Set to `true` to enable inline autocomplete.
*
@@ -1,10 +1,12 @@
import cl from "clsx";
import React, { HTMLAttributes, forwardRef, isValidElement } from "react";
import React, { HTMLAttributes, forwardRef, useRef } from "react";
import { BodyShort, Heading } from "../../typography";
import { useId } from "../../util/hooks";
import ErrorSummaryItem, { ErrorSummaryItemType } from "./ErrorSummaryItem";
import { composeEventHandlers } from "../../util/composeEventHandlers";
import { useMergeRefs } from "../../util/hooks";
import ErrorSummaryItem from "./ErrorSummaryItem";
export interface ErrorSummaryProps extends HTMLAttributes<HTMLDivElement> {
export interface ErrorSummaryProps
extends Omit<HTMLAttributes<HTMLDivElement>, "tabIndex"> {
/**
* Collection of `ErrorSummary.Item`.
*/
@@ -16,6 +18,7 @@ export interface ErrorSummaryProps extends HTMLAttributes<HTMLDivElement> {
size?: "medium" | "small";
/**
* Heading above links.
* @default "Du må rette disse feilene før du kan fortsette:"
*/
heading?: React.ReactNode;
/**
@@ -30,22 +33,22 @@ interface ErrorSummaryComponent
ErrorSummaryProps & React.RefAttributes<HTMLDivElement>
> {
/**
* Link to error.
* Error message with link to field.
*
* @see [🤖 OverridableComponent](https://aksel.nav.no/grunnleggende/kode/overridablecomponent) support
*
* @example
* ```jsx
* <ErrorSummary.Item href="#1">
* <ErrorSummary.Item href="#id-til-alderfelt">
* Felt må fylles ut med alder
* </ErrorSummary.Item>
* ```
*/
Item: ErrorSummaryItemType;
Item: typeof ErrorSummaryItem;
}
/**
* A component that displays a summary of errors.
* Summary of errors in a form.
*
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/errorsummary)
* @see 🏷️ {@link ErrorSummaryProps}
@@ -69,16 +72,19 @@ export const ErrorSummary = forwardRef<HTMLDivElement, ErrorSummaryProps>(
className,
size = "medium",
headingTag = "h2",
heading,
heading = "Du må rette disse feilene før du kan fortsette:",
...rest
},
ref,
) => {
const headingId = useId();
const wrapperRef = useRef<HTMLDivElement>(null);
const headingRef = useRef<HTMLHeadingElement>(null);
const mergedRef = useMergeRefs(ref, wrapperRef);
return (
<section
ref={ref}
<div
ref={mergedRef}
{...rest}
className={cl(
className,
@@ -86,27 +92,25 @@ export const ErrorSummary = forwardRef<HTMLDivElement, ErrorSummaryProps>(
`navds-error-summary--${size}`,
)}
tabIndex={-1}
aria-live="polite"
aria-relevant="all"
aria-labelledby={headingId}
onFocus={composeEventHandlers(rest.onFocus, (event) => {
if (event.target === wrapperRef.current) {
headingRef?.current?.focus();
}
})}
>
<Heading
className="navds-error-summary__heading"
as={headingTag}
size="small"
id={headingId}
ref={headingRef}
tabIndex={-1}
>
{heading}
</Heading>
<BodyShort as="ul" size={size} className="navds-error-summary__list">
{React.Children.map(children, (child) => {
if (!isValidElement(child)) {
return null;
}
return <li key={child.toString()}>{child}</li>;
})}
{children}
</BodyShort>
</section>
</div>
);
},
) as ErrorSummaryComponent;
@@ -14,7 +14,7 @@ export interface ErrorSummaryItemProps
href?: string;
}
export type ErrorSummaryItemType = OverridableComponent<
type ErrorSummaryItemType = OverridableComponent<
ErrorSummaryItemProps,
HTMLAnchorElement
>;
@@ -22,13 +22,15 @@ export type ErrorSummaryItemType = OverridableComponent<
export const ErrorSummaryItem: ErrorSummaryItemType = forwardRef(
({ children, as: Component = "a", className, ...rest }, ref) => {
return (
<Component
{...rest}
ref={ref}
className={cl(className, "navds-error-summary__item", "navds-link")}
>
{children}
</Component>
<li>
<Component
{...rest}
ref={ref}
className={cl(className, "navds-error-summary__item", "navds-link")}
>
{children}
</Component>
</li>
);
},
);
@@ -1,12 +1,34 @@
import { Meta, StoryObj } from "@storybook/react";
import React from "react";
import { expect, userEvent, within } from "@storybook/test";
import React, { useRef } from "react";
import { VStack } from "../../layout/stack";
import { ErrorSummary } from "./ErrorSummary";
export default {
title: "ds-react/Errorsummary",
title: "ds-react/ErrorSummary",
component: ErrorSummary,
parameters: {
chromatic: { disable: true },
},
} satisfies Meta<typeof ErrorSummary>;
type Story = StoryObj<typeof ErrorSummary>;
export const Default: Story = {
render: ({ headingTag, ...rest }) => (
<ErrorSummary headingTag={headingTag || undefined} {...rest}>
<ErrorSummary.Item href="#1">Checkbox må fylles ut</ErrorSummary.Item>
<ErrorSummary.Item href="#2">
Tekstfeltet må ha en godkjent e-mail
</ErrorSummary.Item>
</ErrorSummary>
),
argTypes: {
heading: {
control: {
type: "text",
},
},
headingTag: {
control: {
type: "text",
@@ -19,26 +41,6 @@ export default {
options: ["medium", "small"],
},
},
parameters: {
chromatic: { disable: true },
},
} satisfies Meta<typeof ErrorSummary>;
type Story = StoryObj<typeof ErrorSummary>;
export const Default: Story = {
render: (props) => (
<ErrorSummary
heading="Feiloppsummering komponent"
headingTag={props.headingTag || "h2"}
size={props.size ?? undefined}
>
<ErrorSummary.Item href="#1">Checkbox må fylles ut</ErrorSummary.Item>
<ErrorSummary.Item href="#2">
Tekstfeltet må ha en godkjent e-mail
</ErrorSummary.Item>
</ErrorSummary>
),
};
export const Small: Story = {
@@ -52,6 +54,59 @@ export const Small: Story = {
),
};
export const A11yDemo: Story = {
name: "A11y Demo",
render: () => {
const ref = useRef<HTMLHeadingElement>(null);
return (
<div>
<button
onClick={() => {
ref.current?.focus();
}}
>
Fokuser ErrorSummary
</button>
<ErrorSummary heading="Feiloppsummering tittel" ref={ref}>
<ErrorSummary.Item href="#1">Checkbox må fylles ut</ErrorSummary.Item>
<ErrorSummary.Item href="#2">
Tekstfeltet må ha en godkjent e-mail
</ErrorSummary.Item>
</ErrorSummary>
</div>
);
},
};
export const FocusDemo: Story = {
render: () => {
const ref = useRef<HTMLHeadingElement>(null);
return (
<div>
<button onClick={() => ref.current?.focus()}>Focus summary</button>
<ErrorSummary heading="Feiloppsummering tittel" ref={ref}>
<ErrorSummary.Item href="#1">Checkbox må fylles ut</ErrorSummary.Item>
<ErrorSummary.Item href="#2">
Tekstfeltet må ha en godkjent e-mail
</ErrorSummary.Item>
</ErrorSummary>
</div>
);
},
play: async ({ canvasElement, step }) => {
const canvas = within(canvasElement);
const button = canvas.getByText("Focus summary");
const heading = canvas.getByText("Feiloppsummering tittel");
await step("click button", async () => {
await userEvent.click(button);
});
expect(heading).toHaveFocus();
},
};
export const Chromatic: Story = {
render: () => (
<VStack gap="4">
@@ -2,11 +2,7 @@ import { Meta, StoryFn, StoryObj } from "@storybook/react";
import { fireEvent, within } from "@storybook/test";
import React from "react";
import { ImageIcon } from "@navikt/aksel-icons";
import {
type FileObject,
UNSAFE_FileUpload as FileUpload,
type FilesPartitioned,
} from ".";
import { type FileObject, FileUpload, type FilesPartitioned } from ".";
const meta: Meta<typeof FileUpload.Dropzone> = {
title: "ds-react/FileUpload/Dropzone",
@@ -1,6 +1,6 @@
import { Meta, StoryFn } from "@storybook/react";
import React from "react";
import { FileItem, UNSAFE_FileUpload as FileUpload } from ".";
import { FileItem, FileUpload } from ".";
import { VStack } from "../../layout/stack";
const meta: Meta<typeof FileUpload.Item> = {
@@ -1,7 +1,7 @@
import { Meta, StoryFn } from "@storybook/react";
import React, { useEffect, useState } from "react";
import { UploadIcon } from "@navikt/aksel-icons";
import { UNSAFE_FileUpload as FileUpload, FileUploadItemProps } from ".";
import { FileUpload, FileUploadItemProps } from ".";
import { Alert } from "../../alert";
import { Button } from "../../button";
import { VStack } from "../../layout/stack";
@@ -1,9 +1,9 @@
"use client";
export { default as UNSAFE_FileUpload } from "./FileUpload";
export { default as UNSAFE_FileUploadDropzone } from "./parts/dropzone/Dropzone";
export { default as FileUpload } from "./FileUpload";
export { default as FileUploadDropzone } from "./parts/dropzone/Dropzone";
export { type FileUploadDropzoneProps } from "./parts/dropzone/dropzone.types";
export {
default as UNSAFE_FileUploadTrigger,
default as FileUploadTrigger,
type FileUploadTriggerProps,
} from "./parts/Trigger";
export {
@@ -15,7 +15,7 @@ export {
type FileRejectionReason,
} from "./FileUpload.types";
export {
default as UNSAFE_FileUploadItem,
default as FileUploadItem,
type FileUploadItemProps,
} from "./parts/item/Item";
export { type FileItem, type FileMetadata } from "./parts/item/Item.types";
@@ -1,6 +1,7 @@
import { Meta, StoryFn } from "@storybook/react";
import React, { useState } from "react";
import VStack from "../../layout/stack/VStack";
import UNSAFE_AkselLanguageProvider from "../../provider/i18n/LanguageProvider";
import FormProgress, { FormProgressProps } from "./FormProgress";
export default {
@@ -37,6 +38,97 @@ export const Default: StoryFn<ControllableProps> = (props) => (
);
Default.args = { activeStep: 2, totalSteps: 7, interactiveSteps: true };
export const ProvidedTranslations: StoryFn = () => {
const translations = {
FormProgress: {
step: "Step {activeStep} of {totalSteps}",
showAllSteps: "Show all steps",
hideAllSteps: "Hide all steps",
},
};
return (
<UNSAFE_AkselLanguageProvider translations={translations}>
<FormProgress activeStep={2} totalSteps={7} interactiveSteps>
<FormProgress.Step href="#" completed>
Start søknad
</FormProgress.Step>
<FormProgress.Step href="#">Personopplysninger</FormProgress.Step>
<FormProgress.Step interactive={false}>
Saksopplysninger
</FormProgress.Step>
<FormProgress.Step interactive={false}>
Søknadstekst for en veldig spesifikk prosess i NAV som har lang tekst
</FormProgress.Step>
<FormProgress.Step href="#">Vedlegg</FormProgress.Step>
<FormProgress.Step href="#">Oppsummering</FormProgress.Step>
<FormProgress.Step href="#">Innsending</FormProgress.Step>
</FormProgress>
</UNSAFE_AkselLanguageProvider>
);
};
export const DefaultTranslations: StoryFn = () => {
return (
<UNSAFE_AkselLanguageProvider>
<FormProgress activeStep={2} totalSteps={7} interactiveSteps>
<FormProgress.Step href="#" completed>
Start søknad
</FormProgress.Step>
<FormProgress.Step href="#">Personopplysninger</FormProgress.Step>
<FormProgress.Step interactive={false}>
Saksopplysninger
</FormProgress.Step>
<FormProgress.Step interactive={false}>
Søknadstekst for en veldig spesifikk prosess i NAV som har lang tekst
</FormProgress.Step>
<FormProgress.Step href="#">Vedlegg</FormProgress.Step>
<FormProgress.Step href="#">Oppsummering</FormProgress.Step>
<FormProgress.Step href="#">Innsending</FormProgress.Step>
</FormProgress>
</UNSAFE_AkselLanguageProvider>
);
};
export const ComponentTranslations: StoryFn = () => {
const globalTranslations = {
FormProgress: {
step: "Step {activeStep} of {totalSteps}",
showAllSteps: "Show all steps",
hideAllSteps: "Hide all steps",
},
};
const translations = {
step: "Skref {activeStep} af {totalSteps}",
showAllSteps: "Sýndu öll skref",
hideAllSteps: "Fela öll skref",
};
return (
<UNSAFE_AkselLanguageProvider translations={globalTranslations}>
<FormProgress
translations={translations}
activeStep={2}
totalSteps={7}
interactiveSteps
>
<FormProgress.Step href="#" completed>
Start søknad
</FormProgress.Step>
<FormProgress.Step href="#">Personopplysninger</FormProgress.Step>
<FormProgress.Step interactive={false}>
Saksopplysninger
</FormProgress.Step>
<FormProgress.Step interactive={false}>
Søknadstekst for en veldig spesifikk prosess i NAV som har lang tekst
</FormProgress.Step>
<FormProgress.Step href="#">Vedlegg</FormProgress.Step>
<FormProgress.Step href="#">Oppsummering</FormProgress.Step>
<FormProgress.Step href="#">Innsending</FormProgress.Step>
</FormProgress>
</UNSAFE_AkselLanguageProvider>
);
};
export const Controlled: StoryFn = () => {
const [open, setOpen] = useState(true);
return (
@@ -22,14 +22,17 @@ export interface FormSummaryEditProps
export const FormSummaryEditLink: OverridableComponent<
FormSummaryEditProps,
HTMLAnchorElement
> = forwardRef(({ children = "Endre svar", className, ...rest }, ref) => (
<Link
ref={ref}
{...rest}
className={cl("navds-form-summary__edit", className)}
>
{children}
</Link>
));
> = forwardRef(
({ children = "Endre svar", className, as = "a", ...rest }, ref) => (
<Link
ref={ref}
as={as}
{...rest}
className={cl("navds-form-summary__edit", className)}
>
{children}
</Link>
),
);
export default FormSummaryEditLink;
@@ -41,8 +41,8 @@ export const useRadio = (props: RadioProps) => {
if (readOnly) {
return;
}
props.onChange && props.onChange(e);
radioGroup?.onChange && radioGroup.onChange(props.value);
props.onChange?.(e);
radioGroup?.onChange?.(props.value);
},
onClick: (e) => {
if (readOnly) {
@@ -144,7 +144,7 @@ export const Search = forwardRef<HTMLInputElement, SearchProps>(
(event: SearchClearEvent) => {
onClear?.(event);
handleChange("");
searchRef.current && searchRef.current?.focus?.();
searchRef.current?.focus?.();
},
[handleChange, onClear],
);
@@ -122,7 +122,7 @@ export const Switch = forwardRef<HTMLInputElement, SwitchProps>(
return;
}
setChecked(e.target.checked);
props.onChange && props.onChange(e);
props.onChange?.(e);
}}
onClick={(e) => {
if (readOnly) {
@@ -49,7 +49,7 @@ Default.argTypes = {
export const Open: StoryFn = () => {
const ref = useRef<HTMLButtonElement | null>(null);
useEffect(() => {
ref.current && ref.current.click();
ref.current?.click();
}, []);
return (
+1 -1
View File
@@ -127,7 +127,7 @@ export {
export { ErrorSummary, type ErrorSummaryProps } from "./form/error-summary";
export { Fieldset, type FieldsetProps } from "./form/fieldset";
export {
UNSAFE_FileUpload,
FileUpload,
type FileAccepted,
type FileItem,
type FileMetadata,
@@ -63,7 +63,7 @@ export const PageBlock: OverridableComponent<PageBlockProps, HTMLDivElement> =
{...rest}
className={cl(
"navds-pageblock",
`navds-pageblock--${width}`,
width && `navds-pageblock--${width}`,
className,
{ "navds-pageblock--gutters": gutters },
)}
@@ -26,8 +26,8 @@ export type HStackProps = PrimitiveAsChildProps & Omit<StackProps, "direction">;
* </HStack>
*/
export const HStack: OverridableComponent<HStackProps, HTMLDivElement> =
forwardRef((props, ref) => {
return <Stack {...props} ref={ref} direction="row" />;
forwardRef(({ as = "div", ...rest }, ref) => {
return <Stack as={as} {...rest} ref={ref} direction="row" />;
});
export default HStack;
@@ -27,8 +27,10 @@ export type VStackProps = PrimitiveAsChildProps &
* </VStack>
*/
export const VStack: OverridableComponent<VStackProps, HTMLDivElement> =
forwardRef((props, ref) => {
return <Stack {...props} ref={ref} direction="column" wrap={false} />;
forwardRef(({ as = "div", ...rest }, ref) => {
return (
<Stack as={as} {...rest} ref={ref} direction="column" wrap={false} />
);
});
export default VStack;
+25 -29
View File
@@ -1,15 +1,27 @@
import cl from "clsx";
import React, { forwardRef, useContext } from "react";
import { BodyShort, Heading } from "../typography";
import { useId } from "../util/hooks";
import { BodyLong, BodyShort, Heading, HeadingProps } from "../typography";
import { ListItem } from "./ListItem";
import { ListContext } from "./context";
import { ListProps } from "./types";
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import type { ListItemProps, ListProps } from "./types";
const headingSizeMap: Record<
Exclude<ListProps["size"], undefined>,
HeadingProps["size"]
> = {
small: "xsmall",
medium: "small",
large: "medium",
};
export interface ListComponent
extends React.ForwardRefExoticComponent<
ListProps & React.RefAttributes<HTMLDivElement>
> {
/**
* @see 🏷️ {@link ListItemProps}
*/
Item: typeof ListItem;
}
@@ -42,47 +54,31 @@ export const List = forwardRef<HTMLDivElement, ListProps>(
},
ref,
) => {
const ariaId = useId();
const { size: contextSize } = useContext(ListContext);
const { isNested, size: _size } = useContext(ListContext);
const listSize = size ?? _size ?? "medium";
const listSize = size ?? contextSize;
return (
<ListContext.Provider
value={{
listType: ListTag,
isNested: isNested === null ? false : true,
size: listSize,
}}
>
<div
<BodyLong
as="div"
{...rest}
size={listSize}
ref={ref}
className={cl("navds-list", `navds-list--${listSize}`, className, {
"navds-list--nested": isNested === null ? false : true,
})}
className={cl("navds-list", `navds-list--${listSize}`, className)}
>
{title && (
<Heading
id={`tittel-${ariaId}`}
size={listSize === "medium" ? "small" : "xsmall"}
as={headingTag}
>
<Heading size={headingSizeMap[listSize]} as={headingTag}>
{title}
</Heading>
)}
{description && (
<BodyShort size={listSize} id={`description-${ariaId}`}>
{description}
</BodyShort>
)}
<ListTag
aria-labelledby={title && `tittel-${ariaId}`}
aria-describedby={description && `description-${ariaId}`}
>
{children}
</ListTag>
</div>
{description && <BodyShort size={listSize}>{description}</BodyShort>}
<ListTag role="list">{children}</ListTag>
</BodyLong>
</ListContext.Provider>
);
},
+6 -6
View File
@@ -2,7 +2,7 @@ import cl from "clsx";
import React, { forwardRef, useContext } from "react";
import { BodyLong } from "../typography";
import { ListContext } from "./context";
import { ListItemProps } from "./types";
import type { ListItemProps } from "./types";
/**
* @see 🏷️ {@link ListItemProps}
@@ -21,7 +21,7 @@ export const ListItem = forwardRef<HTMLLIElement, ListItemProps>(
<li {...rest} ref={ref} className={cl("navds-list__item", className)}>
{listType === "ul" && (
<div
className={cl({
className={cl("navds-list__item-marker", {
"navds-list__item-marker--icon": icon,
"navds-list__item-marker--bullet": !icon,
})}
@@ -30,8 +30,8 @@ export const ListItem = forwardRef<HTMLLIElement, ListItemProps>(
icon
) : (
<svg
width="6"
height="6"
width="0.375rem"
height="0.375rem"
viewBox="0 0 6 6"
fill="none"
xmlns="http://www.w3.org/2000/svg"
@@ -45,14 +45,14 @@ export const ListItem = forwardRef<HTMLLIElement, ListItemProps>(
</div>
)}
<BodyLong as="div" size={size} className="navds-list__item-content">
<div>
{title && (
<BodyLong as="p" size={size} weight="semibold">
{title}
</BodyLong>
)}
{children}
</BodyLong>
</div>
</li>
);
},
+2 -4
View File
@@ -2,13 +2,11 @@ import { createContext } from "react";
import { ListProps } from "./types";
interface ListContextProps {
listType: ListProps["as"];
isNested: boolean | null;
size: ListProps["size"];
listType: Exclude<ListProps["as"], undefined>;
size: Exclude<ListProps["size"], undefined>;
}
export const ListContext = createContext<ListContextProps>({
listType: "ul",
isNested: null,
size: "medium",
});
+210 -101
View File
@@ -1,11 +1,13 @@
import { Meta, StoryObj } from "@storybook/react";
import React from "react";
import {
BabyWrappedIcon,
BrailleIcon,
CheckmarkIcon,
ForkIcon,
HeadHeartIcon,
RecycleIcon,
SplitHorizontalIcon,
} from "@navikt/aksel-icons";
import { Box } from "../layout/box";
import { VStack } from "../layout/stack";
import { BodyLong } from "../typography";
import List from "./List";
@@ -20,73 +22,97 @@ export default {
type Story = StoryObj<typeof List>;
export const Default = {
export const Default: Story = {
render: (props) => {
return (
<Box borderWidth="0 0 0 1" borderColor="border-subtle" maxWidth="500px">
<List {...props}>
<List.Item title="Lorem Ipsum Dolor Sit Amet">Beskrivelse.</List.Item>
<List.Item title="Consectetur Adipiscing Elit">
Beskrivelse på punktet i lista. Prøv å hold den kort og konsis.
</List.Item>
<List.Item>
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Iusto
fugiat atque accusantium iure sunt, ipsum voluptas, impedit harum,
minus rerum recusandae.
</List.Item>
<List.Item>
Impedit nemo eos sit adipisci non dolores.
<List>
<List.Item title="Tempor Incididunt">
Error assumenda officia
</List.Item>
<List.Item>Suscipit odit voluptatum</List.Item>
</List>
</List.Item>
<List.Item>
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Iusto
fugiat atque accusantium iure sunt, ipsum voluptas.
<List as="ol">
<List.Item title="Tempor Incididunt">
Error assumenda officia
</List.Item>
<List.Item>Suscipit odit voluptatum</List.Item>
</List>
</List.Item>
</List>
</Box>
);
},
args: {
title: "",
description: "",
},
argTypes: {
size: { control: { type: "radio" }, options: ["small", "medium", "large"] },
as: { control: { type: "radio" }, options: ["ul", "ol"] },
},
};
export const Ordered: Story = {
render: () => {
return (
<List>
<List.Item title="Lorem Ipsum Dolor Sit Amet">
Lorem Ipsum Dolor Sit Amet
</List.Item>
<List.Item title="Consectetur Adipiscing Elit">
Beskrivelse på punktet i lista. Prøv å hold den kort og konsis.
</List.Item>
<List.Item>
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Iusto fugiat
atque accusantium iure sunt, ipsum voluptas, impedit harum, minus
rerum recusandae. Consequuntur sint distinctio nulla reprehenderit eum
suscipit quae libero.
</List.Item>
<List.Item>
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Iusto fugiat
atque accusantium iure sunt, ipsum voluptas, impedit harum, minus
rerum recusandae. Consequuntur sint distinctio nulla reprehenderit eum
suscipit quae libero.
</List.Item>
</List>
<Box borderWidth="0 0 0 1" borderColor="border-subtle" maxWidth="500px">
<List as="ol">
<List.Item title="Lorem Ipsum Dolor Sit Amet">Beskrivelse.</List.Item>
<List.Item title="Consectetur Adipiscing Elit">
Beskrivelse på punktet i lista. Prøv å hold den kort og konsis.
</List.Item>
<List.Item title="Quis Nostrud Exercitation Ullamco Eu Fugiat Nulla Pariatur Dolore">
Beskrivelse på punktet i lista. Prøv å hold den kort og konsis. Men
hvis den likevel blir lang, skal teksten brekke.
</List.Item>
<List.Item>Sed Do Eiusmod Tempor Incididunt</List.Item>
<List.Item>Ut Labore Et Dolore Magna Aliqua</List.Item>
<List.Item>Enim Ad Minim Veniam</List.Item>
<List.Item>Laboris Nisi Ut Aliquip Ex Ea Commodo</List.Item>
<List.Item>Duis Aute Irure Dolor In Reprehenderit</List.Item>
<List.Item>
Impedit nemo eos sit adipisci non dolores.
<List as="ol">
<List.Item title="Tempor Incididunt">
Error assumenda officia
</List.Item>
<List.Item>Suscipit odit voluptatum</List.Item>
</List>
</List.Item>
<List.Item title="Voluptate Velit Esse Cillum Dolore">
Beskrivelse på punktet i lista. Prøv å hold den kort og konsis.
<List>
<List.Item title="Tempor Incididunt">
Error assumenda officia
</List.Item>
<List.Item>Suscipit odit voluptatum</List.Item>
</List>
</List.Item>
<List.Item>Eu Fugiat Nulla Pariatur</List.Item>
</List>
</Box>
);
},
};
export const Ordered = {
render: () => {
return (
<List as="ol">
<List.Item title="Lorem Ipsum Dolor Sit Amet">
Lorem Ipsum Dolor Sit Amet
</List.Item>
<List.Item title="Consectetur Adipiscing Elit">
Beskrivelse på punktet i lista. Prøv å hold den kort og konsis.
</List.Item>
<List.Item title="Sed Do Eiusmod Tempor Incididunt">
Beskrivelse på punktet i lista. Prøv å hold den kort og konsis.
</List.Item>
<List.Item title="Ut Labore Et Dolore Magna Aliqua">
Beskrivelse på punktet i lista. Prøv å hold den kort og konsis.
</List.Item>
<List.Item title="Enim Ad Minim Veniam">
Beskrivelse på punktet i lista. Prøv å hold den kort og konsis.
</List.Item>
<List.Item title="Quis Nostrud Exercitation Ullamco">
Beskrivelse på punktet i lista. Prøv å hold den kort og konsis.
</List.Item>
<List.Item title="Laboris Nisi Ut Aliquip Ex Ea Commodo">
Beskrivelse på punktet i lista. Prøv å hold den kort og konsis.
</List.Item>
<List.Item title="Duis Aute Irure Dolor In Reprehenderit">
Beskrivelse på punktet i lista. Prøv å hold den kort og konsis.
</List.Item>
<List.Item title="Voluptate Velit Esse Cillum Dolore">
Beskrivelse på punktet i lista. Prøv å hold den kort og konsis.
</List.Item>
<List.Item title="Eu Fugiat Nulla Pariatur">
Beskrivelse på punktet i lista. Prøv å hold den kort og konsis.
</List.Item>
</List>
);
},
};
export const WithHeading = {
export const WithHeading: Story = {
render: () => {
return (
<List
@@ -107,10 +133,25 @@ export const WithHeading = {
},
};
export const SizesUl = {
export const SizesUl: Story = {
render: () => {
return (
<VStack gap="8">
<List
title="Large list"
description="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam vel risus volutpat."
size="large"
>
<List.Item title="Lorem Ipsum Dolor Sit Amet">
Beskrivelsen på punkter er nærmere forklart <a href="/">her</a>
</List.Item>
<List.Item title="Consectetur Adipiscing Elit">
Beskrivelsen på punkter er nærmere forklart <a href="/">her</a>
</List.Item>
<List.Item>
Beskrivelsen på punkter er nærmere forklart <a href="/">her</a>
</List.Item>
</List>
<List
title="Medium list"
description="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam vel risus volutpat."
@@ -146,10 +187,26 @@ export const SizesUl = {
},
};
export const SizesOl = {
export const SizesOl: Story = {
render: () => {
return (
<VStack gap="8">
<List
title="Large list"
description="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam vel risus volutpat."
size="large"
as="ol"
>
<List.Item title="Lorem Ipsum Dolor Sit Amet">
Beskrivelsen på punkter er nærmere forklart <a href="/">her</a>
</List.Item>
<List.Item title="Consectetur Adipiscing Elit">
Beskrivelsen på punkter er nærmere forklart <a href="/">her</a>
</List.Item>
<List.Item>
Beskrivelsen på punkter er nærmere forklart <a href="/">her</a>
</List.Item>
</List>
<List
title="Medium list"
description="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam vel risus volutpat."
@@ -187,10 +244,31 @@ export const SizesOl = {
},
};
export const SizesIcons = {
export const SizesIcons: Story = {
render: () => {
return (
<VStack gap="8">
<List
title="Large list"
description="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam vel risus volutpat."
size="large"
>
<List.Item
icon={<HeadHeartIcon aria-hidden />}
title="Lorem Ipsum Dolor Sit Amet"
>
Beskrivelsen på punkter er nærmere forklart <a href="/">her</a>
</List.Item>
<List.Item
icon={<HeadHeartIcon aria-hidden />}
title="Consectetur Adipiscing Elit"
>
Beskrivelsen på punkter er nærmere forklart <a href="/">her</a>
</List.Item>
<List.Item icon={<HeadHeartIcon aria-hidden />}>
Beskrivelsen på punkter er nærmere forklart <a href="/">her</a>
</List.Item>
</List>
<List
title="Medium list"
description="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam vel risus volutpat."
@@ -238,10 +316,10 @@ export const SizesIcons = {
},
};
export const Icons = {
export const Icons: Story = {
render: () => {
return (
<List>
<List title="Best title">
<List.Item
title="Lorem Ipsum Dolor Sit Amet"
icon={<BrailleIcon aria-hidden />}
@@ -250,14 +328,14 @@ export const Icons = {
</List.Item>
<List.Item
title="Consectetur Adipiscing Elit"
icon={<HeadHeartIcon aria-hidden />}
icon={<ForkIcon aria-hidden />}
>
Beskrivelsen på punkter er nærmere forklart <a href="/">her</a>
</List.Item>
<List.Item icon={<BabyWrappedIcon aria-hidden />}>
<List.Item icon={<CheckmarkIcon aria-hidden />}>
Beskrivelsen på punkter er nærmere forklart <a href="/">her</a>
</List.Item>
<List.Item icon={<RecycleIcon aria-hidden />}>
<List.Item icon={<SplitHorizontalIcon aria-hidden />}>
Beskrivelsen på punkter er nærmere forklart <a href="/">her</a>
</List.Item>
</List>
@@ -265,39 +343,70 @@ export const Icons = {
},
};
export const Nested = {
export const Tokens: Story = {
render: () => {
return (
<List>
<List.Item title="Sed Do Eiusmod Tempor Incididunt">
Beskrivelsen på punkter er nærmere forklart <a href="/">her</a>
<List>
<List.Item title="Lorem Ipsum Dolor Sit Amet">
Beskrivelsen på punkter er nærmere forklart <a href="/">her</a>
</List.Item>
<List.Item title="Consectetur Adipiscing Elit">
Beskrivelsen på punkter er nærmere forklart <a href="/">her</a>
</List.Item>
<List.Item>
Beskrivelsen på punkter er nærmere forklart <a href="/">her</a>
</List.Item>
<List.Item>
Beskrivelsen på punkter er nærmere forklart <a href="/">her</a>
<List style={{ "--ac-list-marker-color": "red" }}>
<List.Item>Consectetur Adipiscing Elit</List.Item>
<List.Item>
Impedit nemo eos sit adipisci non dolores.
<List
style={{
"--ac-list-marker-icon-color": "blue",
"--ac-list-marker-ul-color": "pink",
}}
>
<List.Item>Error assumenda officia</List.Item>
<List.Item icon={<HeadHeartIcon aria-hidden />}>
Suscipit odit voluptatum
</List.Item>
</List>
</List.Item>
<List.Item>
Beskrivelsen på punkter er nærmere forklart <a href="/">her</a>
<List.Item style={{ "--ac-list-marker-ol-color": "green" }}>
Iusto fugiat atque accusantium iure sunt.
<List as="ol">
<List.Item>Error assumenda officia</List.Item>
</List>
<List>
<List.Item>Suscipit odit voluptatum</List.Item>
</List>
</List.Item>
</List>
);
},
};
export const Spacing = {
export const Spacing: Story = {
render: () => {
return (
<>
<h2>Large</h2>
<BodyLong size="large" spacing>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Sit minus
aliquid, veniam quibusdam saepe autem quia odio? Tenetur dicta
voluptates iste maiores perspiciatis? Sapiente in possimus iusto
numquam? Esse, voluptatibus.
</BodyLong>
<List size="large">
<List.Item>
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Iusto
fugiat atque accusantium iure sunt, ipsum voluptas, impedit harum,
minus rerum recusandae. Consequuntur sint distinctio nulla
reprehenderit eum suscipit quae libero.
</List.Item>
<List.Item>
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Iusto
fugiat atque accusantium iure sunt, ipsum voluptas, impedit harum,
minus rerum recusandae. Consequuntur sint distinctio nulla
reprehenderit eum suscipit quae libero.
</List.Item>
</List>
<BodyLong size="large" spacing>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Sit minus
aliquid, veniam quibusdam saepe autem quia odio? Tenetur dicta
voluptates iste maiores perspiciatis? Sapiente in possimus iusto
numquam? Esse, voluptatibus.
</BodyLong>
<h2>Medium</h2>
<BodyLong spacing>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Sit minus
@@ -358,43 +467,43 @@ export const Spacing = {
};
export const Chromatic: Story = {
render: () => (
render: (...args) => (
<VStack gap="2">
<div>
<h2>Default</h2>
<Default.render />
{Default.render?.(...args)}
</div>
<div>
<h2>Ordered</h2>
<Ordered.render />
{Ordered.render?.(...args)}
</div>
<div>
<h2>WithHeading</h2>
<WithHeading.render />
{WithHeading.render?.(...args)}
</div>
<div>
<h2>SizesUl</h2>
<SizesUl.render />
{SizesUl.render?.(...args)}
</div>
<div>
<h2>SizesOl</h2>
<SizesOl.render />
{SizesOl.render?.(...args)}
</div>
<div>
<h2>SizesIcons</h2>
<SizesIcons.render />
{SizesIcons.render?.(...args)}
</div>
<div>
<h2>Icons</h2>
<Icons.render />
{Icons.render?.(...args)}
</div>
<div>
<h2>Nested</h2>
<Nested.render />
<h2>Tokens</h2>
{Tokens.render?.(...args)}
</div>
<div>
<h2>Spacing</h2>
<Spacing.render />
{Spacing.render?.(...args)}
</div>
</VStack>
),
+2 -2
View File
@@ -19,10 +19,10 @@ export interface ListProps extends React.HTMLAttributes<HTMLDivElement> {
*/
headingTag?: React.ElementType<any>;
/**
* Changes padding, height and font-size.
* Changes margin-block on list and font size on items.
* @default "medium"
*/
size?: "medium" | "small";
size?: "small" | "medium" | "large";
}
export interface ListItemProps extends React.HTMLAttributes<HTMLLIElement> {
+2 -2
View File
@@ -127,7 +127,7 @@ export const Modal = forwardRef<HTMLDialogElement, ModalProps>(
// We have to use JS because it doesn't work to set it with a prop (React bug?)
// Currently doesn't seem to work in Chrome. See also Tooltip.tsx
if (modalRef.current && portalNode) modalRef.current.autofocus = true;
}, [modalRef, portalNode]);
}, [portalNode]);
useEffect(() => {
// We need to have this in a useEffect so that the content renders before the modal is displayed,
@@ -140,7 +140,7 @@ export const Modal = forwardRef<HTMLDialogElement, ModalProps>(
modalRef.current.close();
}
}
}, [modalRef, portalNode, open]);
}, [portalNode, open]);
useBodyScrollLock(modalRef, portalNode, isNested);
Loaded 100 of 311 files, more files were not shown because too many files have changed in this diff. Show more