@fremtind/jokul 5.2.3 → 6.0.0-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/build/build-stats.html +37 -36
- package/build/cjs/components/autosuggest/BaseAutosuggest.cjs +1 -1
- package/build/cjs/components/autosuggest/BaseAutosuggest.cjs.map +1 -1
- package/build/cjs/components/date-input/DateInput.cjs +2 -0
- package/build/cjs/components/date-input/DateInput.cjs.map +1 -0
- package/build/cjs/components/date-input/DateInput.d.cts +7 -0
- package/build/cjs/components/date-input/calendar/Calendar.cjs +2 -0
- package/build/cjs/components/date-input/calendar/Calendar.cjs.map +1 -0
- package/build/cjs/components/date-input/calendar/Calendar.d.cts +6 -0
- package/build/cjs/components/date-input/calendar/CalendarDay.cjs +2 -0
- package/build/cjs/components/date-input/calendar/CalendarDay.cjs.map +1 -0
- package/build/cjs/components/date-input/calendar/CalendarDay.d.cts +16 -0
- package/build/cjs/components/date-input/calendar/CalendarWeek.cjs +2 -0
- package/build/cjs/components/date-input/calendar/CalendarWeek.cjs.map +1 -0
- package/build/cjs/components/date-input/calendar/CalendarWeek.d.cts +8 -0
- package/build/cjs/components/date-input/calendar/types.d.cts +6 -0
- package/build/cjs/components/date-input/calendar/utils.cjs +2 -0
- package/build/cjs/components/date-input/calendar/utils.cjs.map +1 -0
- package/build/cjs/components/date-input/calendar/utils.d.cts +19 -0
- package/build/cjs/components/date-input/index.cjs +2 -0
- package/build/cjs/components/date-input/index.d.cts +3 -0
- package/build/cjs/components/date-input/types.d.cts +35 -0
- package/build/cjs/components/date-input/utils.cjs +2 -0
- package/build/cjs/components/date-input/utils.cjs.map +1 -0
- package/build/cjs/components/date-input/utils.d.cts +34 -0
- package/build/cjs/components/file/File.cjs +1 -1
- package/build/cjs/components/file/File.cjs.map +1 -1
- package/build/cjs/components/file/types.d.cts +10 -1
- package/build/cjs/components/search/Search.cjs +1 -1
- package/build/cjs/components/search/Search.cjs.map +1 -1
- package/build/cjs/components/select/Option.cjs +2 -0
- package/build/cjs/components/select/Option.cjs.map +1 -0
- package/build/cjs/components/select/Option.d.cts +12 -0
- package/build/cjs/components/select/Select.cjs +1 -1
- package/build/cjs/components/select/Select.cjs.map +1 -1
- package/build/cjs/components/select/Select.d.cts +18 -3
- package/build/cjs/components/select/index.cjs +1 -1
- package/build/cjs/components/select/index.d.cts +1 -5
- package/build/cjs/components/select/utils.cjs +2 -0
- package/build/cjs/components/select/utils.cjs.map +1 -0
- package/build/cjs/components/select/utils.d.cts +5 -0
- package/build/cjs/components/table/TablePagination.cjs +1 -1
- package/build/cjs/components/table/TablePagination.cjs.map +1 -1
- package/build/cjs/components/tabs/Tabs.cjs.map +1 -1
- package/build/cjs/hooks/index.cjs +1 -1
- package/build/cjs/hooks/index.d.cts +0 -1
- package/build/cjs/hooks/useListNavigation/useListNavigation.cjs +1 -1
- package/build/cjs/hooks/useListNavigation/useListNavigation.cjs.map +1 -1
- package/build/cjs/hooks/useListNavigation/useListNavigation.d.cts +4 -2
- package/build/cjs/utilities/formatters/index.cjs +1 -1
- package/build/cjs/utilities/formatters/index.d.cts +1 -1
- package/build/cjs/utilities/formatters/util/registerWithMask.cjs +1 -1
- package/build/cjs/utilities/formatters/util/registerWithMask.cjs.map +1 -1
- package/build/cjs/utilities/formatters/util/registerWithMask.d.cts +0 -8
- package/build/cjs/utilities/index.cjs +1 -1
- package/build/cjs/utilities/validators/index.cjs +1 -1
- package/build/cjs/utilities/validators/index.d.cts +0 -1
- package/build/cjs/utilities/valuePair.cjs.map +1 -1
- package/build/cjs/utilities/valuePair.d.cts +2 -0
- package/build/es/components/autosuggest/BaseAutosuggest.js +1 -1
- package/build/es/components/autosuggest/BaseAutosuggest.js.map +1 -1
- package/build/es/components/date-input/DateInput.d.ts +7 -0
- package/build/es/components/date-input/DateInput.js +2 -0
- package/build/es/components/date-input/DateInput.js.map +1 -0
- package/build/es/components/date-input/calendar/Calendar.d.ts +6 -0
- package/build/es/components/date-input/calendar/Calendar.js +2 -0
- package/build/es/components/date-input/calendar/Calendar.js.map +1 -0
- package/build/es/components/date-input/calendar/CalendarDay.d.ts +16 -0
- package/build/es/components/date-input/calendar/CalendarDay.js +2 -0
- package/build/es/components/date-input/calendar/CalendarDay.js.map +1 -0
- package/build/es/components/date-input/calendar/CalendarWeek.d.ts +8 -0
- package/build/es/components/date-input/calendar/CalendarWeek.js +2 -0
- package/build/es/components/date-input/calendar/CalendarWeek.js.map +1 -0
- package/build/es/components/date-input/calendar/types.d.ts +6 -0
- package/build/es/components/date-input/calendar/utils.d.ts +19 -0
- package/build/es/components/date-input/calendar/utils.js +2 -0
- package/build/es/components/date-input/calendar/utils.js.map +1 -0
- package/build/es/components/date-input/index.d.ts +3 -0
- package/build/es/components/date-input/index.js +2 -0
- package/build/es/components/date-input/types.d.ts +35 -0
- package/build/es/components/date-input/utils.d.ts +34 -0
- package/build/es/components/date-input/utils.js +2 -0
- package/build/es/components/date-input/utils.js.map +1 -0
- package/build/es/components/file/File.js +1 -1
- package/build/es/components/file/File.js.map +1 -1
- package/build/es/components/file/types.d.ts +10 -1
- package/build/es/components/search/Search.js +1 -1
- package/build/es/components/search/Search.js.map +1 -1
- package/build/es/components/select/Option.d.ts +12 -0
- package/build/es/components/select/Option.js +2 -0
- package/build/es/components/select/Option.js.map +1 -0
- package/build/es/components/select/Select.d.ts +18 -3
- package/build/es/components/select/Select.js +1 -1
- package/build/es/components/select/Select.js.map +1 -1
- package/build/es/components/select/index.d.ts +1 -5
- package/build/es/components/select/index.js +1 -1
- package/build/es/components/select/utils.d.ts +5 -0
- package/build/es/components/select/utils.js +2 -0
- package/build/es/components/select/utils.js.map +1 -0
- package/build/es/components/table/TablePagination.js +1 -1
- package/build/es/components/table/TablePagination.js.map +1 -1
- package/build/es/components/tabs/Tabs.js.map +1 -1
- package/build/es/hooks/index.d.ts +0 -1
- package/build/es/hooks/index.js +1 -1
- package/build/es/hooks/useListNavigation/useListNavigation.d.ts +4 -2
- package/build/es/hooks/useListNavigation/useListNavigation.js +1 -1
- package/build/es/hooks/useListNavigation/useListNavigation.js.map +1 -1
- package/build/es/utilities/formatters/index.d.ts +1 -1
- package/build/es/utilities/formatters/index.js +1 -1
- package/build/es/utilities/formatters/util/registerWithMask.d.ts +0 -8
- package/build/es/utilities/formatters/util/registerWithMask.js +1 -1
- package/build/es/utilities/formatters/util/registerWithMask.js.map +1 -1
- package/build/es/utilities/index.js +1 -1
- package/build/es/utilities/validators/index.d.ts +0 -1
- package/build/es/utilities/validators/index.js +1 -1
- package/build/es/utilities/valuePair.d.ts +2 -0
- package/build/es/utilities/valuePair.js.map +1 -1
- package/codemods/CODEMODS.md +55 -0
- package/codemods/__tests__/import-paths.test.mjs +155 -0
- package/codemods/import-paths.mjs +10 -2
- package/codemods/transforms/date-input.mjs +225 -0
- package/codemods/transforms/import-specifiers.mjs +26 -0
- package/codemods/transforms/register-with-mask.mjs +267 -0
- package/package.json +14 -13
- package/src/fonts/Jokul-Icons.woff2 +0 -0
- package/src/fonts/brands/fremtind/Jokul-Icons.woff2 +0 -0
- package/styles/base.css +8 -1
- package/styles/base.min.css +1 -1
- package/styles/components/autosuggest/autosuggest.min.css +1 -1
- package/styles/components/beta/description-list/description-list.min.css +1 -1
- package/styles/components/beta/nav-link/navlink.min.css +1 -1
- package/styles/components/breadcrumb/breadcrumb.min.css +1 -1
- package/styles/components/button/button.min.css +1 -1
- package/styles/components/card/card.min.css +1 -1
- package/styles/components/checkbox/checkbox.min.css +1 -1
- package/styles/components/checkbox-panel/checkbox-panel.min.css +1 -1
- package/styles/components/checkbox-panel/development/styles.min.css +1 -1
- package/styles/components/chip/chip.min.css +1 -1
- package/styles/components/combobox/combobox.min.css +1 -1
- package/styles/components/cookie-consent/cookie-consent.min.css +1 -1
- package/styles/components/countdown/countdown.css +2 -2
- package/styles/components/countdown/countdown.min.css +1 -1
- package/styles/components/date-input/_index.scss +8 -0
- package/styles/components/date-input/calendar/_index.scss +8 -0
- package/styles/components/date-input/calendar/calendar.css +60 -0
- package/styles/components/date-input/calendar/calendar.min.css +1 -0
- package/styles/components/date-input/calendar/calendar.scss +79 -0
- package/styles/components/date-input/date-input.css +187 -0
- package/styles/components/date-input/date-input.min.css +1 -0
- package/styles/components/date-input/date-input.scss +67 -0
- package/styles/components/description-list/description-list.min.css +1 -1
- package/styles/components/expander/accordion.min.css +1 -1
- package/styles/components/expander/expandable.min.css +1 -1
- package/styles/components/feedback/feedback.css +2 -2
- package/styles/components/feedback/feedback.min.css +1 -1
- package/styles/components/file/file.css +50 -61
- package/styles/components/file/file.min.css +1 -1
- package/styles/components/file/file.scss +66 -79
- package/styles/components/file-input/file-input.css +59 -70
- package/styles/components/file-input/file-input.min.css +1 -1
- package/styles/components/flex/flex.min.css +1 -1
- package/styles/components/help/help.min.css +1 -1
- package/styles/components/icon/icon.css +1 -1
- package/styles/components/icon/icon.min.css +1 -1
- package/styles/components/icon/icon.scss +1 -0
- package/styles/components/icon-button/icon-button.min.css +1 -1
- package/styles/components/image/development/style.min.css +1 -1
- package/styles/components/image/image.min.css +1 -1
- package/styles/components/input-group/input-group.css +2 -2
- package/styles/components/input-group/input-group.min.css +1 -1
- package/styles/components/input-panel/input-panel.min.css +1 -1
- package/styles/components/link/link.min.css +1 -1
- package/styles/components/link-list/link-list.min.css +1 -1
- package/styles/components/list/list.min.css +1 -1
- package/styles/components/loader/loader.css +6 -6
- package/styles/components/loader/loader.min.css +1 -1
- package/styles/components/loader/skeleton-loader.css +3 -3
- package/styles/components/loader/skeleton-loader.min.css +1 -1
- package/styles/components/logo/development/styles.min.css +1 -1
- package/styles/components/logo/logo.min.css +1 -1
- package/styles/components/menu/menu.min.css +1 -1
- package/styles/components/message/message.css +2 -2
- package/styles/components/message/message.min.css +1 -1
- package/styles/components/modal/modal.min.css +1 -1
- package/styles/components/nav-link/nav-link.min.css +1 -1
- package/styles/components/number-input/number-input.min.css +1 -1
- package/styles/components/pagination/development/styles.min.css +1 -1
- package/styles/components/pagination/pagination.min.css +1 -1
- package/styles/components/popover/popover.min.css +1 -1
- package/styles/components/progress-bar/progress-bar.css +1 -1
- package/styles/components/progress-bar/progress-bar.min.css +1 -1
- package/styles/components/radio-button/radio-button.min.css +1 -1
- package/styles/components/radio-panel/development/styles.min.css +1 -1
- package/styles/components/radio-panel/radio-panel.min.css +1 -1
- package/styles/components/search/search-with-submit-button.min.css +1 -1
- package/styles/components/search/search.min.css +1 -1
- package/styles/components/segmented-control/segmented-control.css +3 -3
- package/styles/components/segmented-control/segmented-control.min.css +1 -1
- package/styles/components/select/_index.scss +5 -0
- package/styles/components/select/option.css +73 -0
- package/styles/components/select/option.min.css +1 -0
- package/styles/components/select/option.scss +74 -0
- package/styles/components/select/select.css +84 -264
- package/styles/components/select/select.min.css +1 -1
- package/styles/components/select/select.scss +79 -328
- package/styles/components/summary-table/summary-table.min.css +1 -1
- package/styles/components/system-message/system-message.css +2 -2
- package/styles/components/system-message/system-message.min.css +1 -1
- package/styles/components/table/table.min.css +3 -1
- package/styles/components/table-of-contents/table-of-contents.min.css +1 -1
- package/styles/components/tabs/tabs.min.css +1 -1
- package/styles/components/tag/tag.min.css +1 -1
- package/styles/components/text-area/text-area.min.css +1 -1
- package/styles/components/text-input/text-input.min.css +1 -1
- package/styles/components/toast/toast.css +4 -4
- package/styles/components/toast/toast.min.css +1 -1
- package/styles/components/toggle-switch/toggle-switch.min.css +1 -1
- package/styles/components/tooltip/tooltip.min.css +1 -1
- package/styles/components/typography/title.min.css +1 -1
- package/styles/components.css +4391 -4612
- package/styles/components.min.css +3 -1
- package/styles/components.scss +2 -3
- package/styles/jkl/_shadows.scss +0 -12
- package/styles/theme/_fonts.scss +1 -1
- package/styles/utility/_index.scss +2 -1
- package/styles/utility/_lists.scss +7 -0
- package/build/_commonjsHelpers-C37NGDzP.cjs +0 -2
- package/build/_commonjsHelpers-C37NGDzP.cjs.map +0 -1
- package/build/_commonjsHelpers-CXUWDbkB.js +0 -2
- package/build/_commonjsHelpers-CXUWDbkB.js.map +0 -1
- package/build/cjs/components/beta/select/Select.cjs +0 -2
- package/build/cjs/components/beta/select/Select.cjs.map +0 -1
- package/build/cjs/components/beta/select/Select.d.cts +0 -3
- package/build/cjs/components/beta/select/index.cjs +0 -2
- package/build/cjs/components/beta/select/index.d.cts +0 -2
- package/build/cjs/components/beta/select/types.d.cts +0 -10
- package/build/cjs/components/datepicker/DatePicker.cjs +0 -2
- package/build/cjs/components/datepicker/DatePicker.cjs.map +0 -1
- package/build/cjs/components/datepicker/DatePicker.d.cts +0 -3
- package/build/cjs/components/datepicker/index.cjs +0 -2
- package/build/cjs/components/datepicker/index.cjs.map +0 -1
- package/build/cjs/components/datepicker/index.d.cts +0 -4
- package/build/cjs/components/datepicker/internal/Calendar.cjs +0 -2
- package/build/cjs/components/datepicker/internal/Calendar.cjs.map +0 -1
- package/build/cjs/components/datepicker/internal/Calendar.d.cts +0 -15
- package/build/cjs/components/datepicker/internal/calendarReducer.cjs +0 -2
- package/build/cjs/components/datepicker/internal/calendarReducer.cjs.map +0 -1
- package/build/cjs/components/datepicker/internal/calendarReducer.d.cts +0 -18
- package/build/cjs/components/datepicker/internal/useCalendar.cjs +0 -2
- package/build/cjs/components/datepicker/internal/useCalendar.cjs.map +0 -1
- package/build/cjs/components/datepicker/internal/useCalendar.d.cts +0 -59
- package/build/cjs/components/datepicker/internal/utils.cjs +0 -2
- package/build/cjs/components/datepicker/internal/utils.cjs.map +0 -1
- package/build/cjs/components/datepicker/internal/utils.d.cts +0 -167
- package/build/cjs/components/datepicker/types.d.cts +0 -280
- package/build/cjs/components/datepicker/utils.cjs +0 -2
- package/build/cjs/components/datepicker/utils.cjs.map +0 -1
- package/build/cjs/components/datepicker/utils.d.cts +0 -22
- package/build/cjs/components/datepicker/validation.cjs +0 -2
- package/build/cjs/components/datepicker/validation.cjs.map +0 -1
- package/build/cjs/components/datepicker/validation.d.cts +0 -4
- package/build/cjs/components/select/NativeSelect.cjs +0 -2
- package/build/cjs/components/select/NativeSelect.cjs.map +0 -1
- package/build/cjs/components/select/NativeSelect.d.cts +0 -3
- package/build/cjs/components/select/select-utils.cjs +0 -2
- package/build/cjs/components/select/select-utils.cjs.map +0 -1
- package/build/cjs/components/select/select-utils.d.cts +0 -2
- package/build/cjs/components/select/types.cjs +0 -2
- package/build/cjs/components/select/types.cjs.map +0 -1
- package/build/cjs/components/select/types.d.cts +0 -66
- package/build/cjs/hooks/useAnimatedDetails/index.cjs +0 -2
- package/build/cjs/hooks/useAnimatedDetails/index.cjs.map +0 -1
- package/build/cjs/hooks/useAnimatedDetails/index.d.cts +0 -1
- package/build/cjs/hooks/useAnimatedDetails/useAnimatedDetails.cjs +0 -2
- package/build/cjs/hooks/useAnimatedDetails/useAnimatedDetails.cjs.map +0 -1
- package/build/cjs/hooks/useAnimatedDetails/useAnimatedDetails.d.cts +0 -21
- package/build/cjs/utilities/validators/isValidDogId/isValidDogId.cjs +0 -2
- package/build/cjs/utilities/validators/isValidDogId/isValidDogId.cjs.map +0 -1
- package/build/cjs/utilities/validators/isValidDogId/isValidDogId.d.cts +0 -7
- package/build/es/components/beta/select/Select.d.ts +0 -3
- package/build/es/components/beta/select/Select.js +0 -2
- package/build/es/components/beta/select/Select.js.map +0 -1
- package/build/es/components/beta/select/index.d.ts +0 -2
- package/build/es/components/beta/select/index.js +0 -2
- package/build/es/components/beta/select/types.d.ts +0 -10
- package/build/es/components/datepicker/DatePicker.d.ts +0 -3
- package/build/es/components/datepicker/DatePicker.js +0 -2
- package/build/es/components/datepicker/DatePicker.js.map +0 -1
- package/build/es/components/datepicker/index.d.ts +0 -4
- package/build/es/components/datepicker/index.js +0 -2
- package/build/es/components/datepicker/index.js.map +0 -1
- package/build/es/components/datepicker/internal/Calendar.d.ts +0 -15
- package/build/es/components/datepicker/internal/Calendar.js +0 -2
- package/build/es/components/datepicker/internal/Calendar.js.map +0 -1
- package/build/es/components/datepicker/internal/calendarReducer.d.ts +0 -18
- package/build/es/components/datepicker/internal/calendarReducer.js +0 -2
- package/build/es/components/datepicker/internal/calendarReducer.js.map +0 -1
- package/build/es/components/datepicker/internal/useCalendar.d.ts +0 -59
- package/build/es/components/datepicker/internal/useCalendar.js +0 -2
- package/build/es/components/datepicker/internal/useCalendar.js.map +0 -1
- package/build/es/components/datepicker/internal/utils.d.ts +0 -167
- package/build/es/components/datepicker/internal/utils.js +0 -2
- package/build/es/components/datepicker/internal/utils.js.map +0 -1
- package/build/es/components/datepicker/types.d.ts +0 -280
- package/build/es/components/datepicker/utils.d.ts +0 -22
- package/build/es/components/datepicker/utils.js +0 -2
- package/build/es/components/datepicker/utils.js.map +0 -1
- package/build/es/components/datepicker/validation.d.ts +0 -4
- package/build/es/components/datepicker/validation.js +0 -2
- package/build/es/components/datepicker/validation.js.map +0 -1
- package/build/es/components/select/NativeSelect.d.ts +0 -3
- package/build/es/components/select/NativeSelect.js +0 -2
- package/build/es/components/select/NativeSelect.js.map +0 -1
- package/build/es/components/select/select-utils.d.ts +0 -2
- package/build/es/components/select/select-utils.js +0 -2
- package/build/es/components/select/select-utils.js.map +0 -1
- package/build/es/components/select/types.d.ts +0 -66
- package/build/es/components/select/types.js +0 -2
- package/build/es/components/select/types.js.map +0 -1
- package/build/es/hooks/useAnimatedDetails/index.d.ts +0 -1
- package/build/es/hooks/useAnimatedDetails/index.js +0 -2
- package/build/es/hooks/useAnimatedDetails/index.js.map +0 -1
- package/build/es/hooks/useAnimatedDetails/useAnimatedDetails.d.ts +0 -21
- package/build/es/hooks/useAnimatedDetails/useAnimatedDetails.js +0 -2
- package/build/es/hooks/useAnimatedDetails/useAnimatedDetails.js.map +0 -1
- package/build/es/utilities/validators/isValidDogId/isValidDogId.d.ts +0 -7
- package/build/es/utilities/validators/isValidDogId/isValidDogId.js +0 -2
- package/build/es/utilities/validators/isValidDogId/isValidDogId.js.map +0 -1
- package/build/utils-C5AH4j8B.js +0 -2
- package/build/utils-C5AH4j8B.js.map +0 -1
- package/build/utils-CD_aHC6R.cjs +0 -2
- package/build/utils-CD_aHC6R.cjs.map +0 -1
- package/src/fonts/Fremtind-Material-Symbols.woff2 +0 -0
- package/src/fonts/brands/fremtind/Fremtind-Material-Symbols.woff2 +0 -0
- package/styles/components/beta/select/_index.scss +0 -3
- package/styles/components/beta/select/select.css +0 -101
- package/styles/components/beta/select/select.min.css +0 -1
- package/styles/components/beta/select/select.scss +0 -99
- package/styles/components/datepicker/_calendar-date-button.scss +0 -72
- package/styles/components/datepicker/_calendar-navigation-dropdown.scss +0 -55
- package/styles/components/datepicker/_calendar-navigation.scss +0 -14
- package/styles/components/datepicker/_calendar-table.scss +0 -29
- package/styles/components/datepicker/_calendar.scss +0 -28
- package/styles/components/datepicker/_index.scss +0 -6
- package/styles/components/datepicker/datepicker.css +0 -246
- package/styles/components/datepicker/datepicker.min.css +0 -1
- package/styles/components/datepicker/datepicker.scss +0 -49
- /package/build/cjs/components/{beta/select → date-input/calendar}/types.cjs +0 -0
- /package/build/cjs/components/{beta/select → date-input/calendar}/types.cjs.map +0 -0
- /package/build/cjs/components/{beta/select → date-input}/index.cjs.map +0 -0
- /package/build/cjs/components/{datepicker → date-input}/types.cjs +0 -0
- /package/build/cjs/components/{datepicker → date-input}/types.cjs.map +0 -0
- /package/build/es/components/{beta/select → date-input/calendar}/types.js +0 -0
- /package/build/es/components/{beta/select → date-input/calendar}/types.js.map +0 -0
- /package/build/es/components/{beta/select → date-input}/index.js.map +0 -0
- /package/build/es/components/{datepicker → date-input}/types.js +0 -0
- /package/build/es/components/{datepicker → date-input}/types.js.map +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),o=require("react"),r=require("../../../clsx-E3yX_9sL.cjs");require("../../hooks/useScreen/useScreen.cjs"),require("../../hooks/useId/useId.cjs");const n=require("../../hooks/useListNavigation/useListNavigation.cjs"),i=require("../../utilities/mergeRefs.cjs"),c=require("../../utilities/valuePair.cjs"),t=require("../button/Button.cjs"),s=require("../flex/Flex.cjs");require("../icon/Icon.cjs"),require("../icon/icons/animated/ArrowVerticalAnimated.cjs"),require("../icon/icons/animated/ArrowHorizontalAnimated.cjs"),require("../icon/icons/animated/PlusRemoveAnimated.cjs");const a=require("../icon/icons/ArrowDownIcon.cjs");require("../icon/icons/ArrowLeftIcon.cjs"),require("../icon/icons/ArrowNorthEastIcon.cjs"),require("../icon/icons/ArrowRightIcon.cjs"),require("../icon/icons/ArrowUpIcon.cjs"),require("../icon/icons/CalendarIcon.cjs"),require("../icon/icons/CheckIcon.cjs"),require("../icon/icons/ChevronDownIcon.cjs"),require("../icon/icons/ChevronLeftIcon.cjs"),require("../icon/icons/ChevronRightIcon.cjs"),require("../icon/icons/ChevronUpIcon.cjs");const u=require("../icon/icons/CloseIcon.cjs");require("../icon/icons/CopyIcon.cjs"),require("../icon/icons/DotsIcon.cjs"),require("../icon/icons/DragIcon.cjs"),require("../icon/icons/ErrorIcon.cjs"),require("../icon/icons/GreenCheckIcon.cjs"),require("../icon/icons/HamburgerIcon.cjs"),require("../icon/icons/InfoIcon.cjs"),require("../icon/icons/LinkIcon.cjs"),require("../icon/icons/MinusIcon.cjs"),require("../icon/icons/OpenInNewIcon.cjs"),require("../icon/icons/PenIcon.cjs"),require("../icon/icons/PlusIcon.cjs"),require("../icon/icons/QuestionIcon.cjs"),require("../icon/icons/RedCrossIcon.cjs"),require("../icon/icons/SearchIcon.cjs"),require("../icon/icons/SuccessIcon.cjs"),require("../icon/icons/ThumbDownIcon.cjs"),require("../icon/icons/ThumbUpIcon.cjs"),require("../icon/icons/TrashCanIcon.cjs"),require("../icon/icons/WarningIcon.cjs");const l=require("../input-group/InputGroup.cjs"),d=require("../search/Search.cjs"),p=require("../typography/Text.cjs"),j=require("../typography/Title.cjs"),h=require("./Option.cjs"),v=require("./utils.cjs"),b=o.forwardRef(function(b,q){const{label:f,errorLabel:g,helpLabel:I,labelProps:m,supportLabelProps:x,tooltip:w,description:y,style:L,className:k,id:S,items:C,multiple:E=!1,searchable:A=!1,onSearch:N,filterFunction:T,placeholder:P,width:R,value:D,"data-testautoid":F,"data-size":O,...z}=b,B=o.useRef(null),$=o.useRef(null),_=i.mergeRefs(q,$),U=`jkl-select-${o.useId()}`,V=S??U,G=`${V}-popover`,[H,M]=o.useState(""),[K,Q]=o.useState(()=>new Set);n.useListNavigation({ref:B,disableTypeahead:A});const W=C.map(c.getValuePair),J=A&&H?W.filter(e=>T?T(e,H):e.label.toLowerCase().includes(H.toLowerCase())):W,X=0===K.size||1===K.size&&P&&K.has(""),Y=P||"Ingen valgt",Z=v.getButtonText(K,W,Y);o.useLayoutEffect(()=>{const e=$.current,o=B.current;if(!e)return;const r=()=>{Q(new Set(Array.from(e.selectedOptions,e=>e.value)))},n=e=>{"closed"===e.newState&&M("")};return r(),o?.addEventListener("toggle",n),e.addEventListener("change",r),()=>{e.removeEventListener("change",r),o?.removeEventListener("toggle",n)}},[E,C]),o.useLayoutEffect(()=>{Q(new Set(Array.from($.current?.selectedOptions??[],e=>e.value)))},[D,z.defaultValue]);const ee=e=>{("ArrowDown"===e.key||"ArrowUp"===e.key)&&(e.preventDefault(),B.current?.showPopover?.())},oe=e=>{const o=$.current;if(!B.current?.contains(e.relatedTarget)){if(!o)return;["focus","focusin"].includes(e.type)?(o.dispatchEvent(new Event("focusin",{bubbles:!0})),o.dispatchEvent(new Event("focus",{bubbles:!0}))):["blur","focusout"].includes(e.type)&&(o.dispatchEvent(new Event("focusout",{bubbles:!0})),o.dispatchEvent(new Event("blur",{bubbles:!0})))}};return e.jsx(l.InputGroup,{id:V,label:f,errorLabel:g,helpLabel:I,labelProps:m,supportLabelProps:x,tooltip:w,description:y,style:L,"data-testautoid":F,"data-size":O,className:r.clsx("jkl-select",k),render:r=>e.jsxs(e.Fragment,{children:[e.jsxs("button",{"aria-label":`${X?Y:Z}, ${v.getReactNodeText(f)}`,className:"jkl-select__button","data-testid":"jkl-select__button",disabled:z.disabled,type:"button",popovertarget:G,style:{"--width":R},onKeyDown:ee,onFocus:oe,onBlur:oe,...r,children:[X?Y:Z,e.jsx(a.ArrowDownIcon,{})]}),e.jsxs(s.Flex,{direction:"column",gap:"16",ref:B,popover:"auto",id:G,className:"jkl-select__popover","aria-label":v.getReactNodeText(f),children:[e.jsxs(s.Flex,{as:"header",alignItems:"start",justifyContent:"space-between",gap:"8",children:[e.jsx(j.Title,{size:"m",as:"h3",id:`${V}-title`,children:f}),e.jsx(t.Button,{type:"button",variant:"ghost",icon:e.jsx(u.CloseIcon,{}),"aria-label":"Lukk",popovertarget:G,popovertargetaction:"hide"})]}),A&&e.jsx(d.Search,{value:H,onChange:e=>{M(e.target.value),N?.(e.target.value)},ref:v.autofocus(A),autoComplete:"off",labelProps:{srOnly:!0},label:"Søk",placeholder:"Søk...",width:"100%",className:"jkl-spacing-8--bottom"}),e.jsxs(s.Flex,{direction:"column",gap:"8",role:"listbox","aria-multiselectable":E,"aria-labelledby":`${V}-title`,children:[J.map((e,r)=>o.createElement(h.Option,{...e,key:e.value,selected:K.has(e.value),multiple:E,selectRef:$,popovertarget:E?void 0:G,popovertargetaction:E?void 0:"hide",ref:v.autofocus(()=>!A&&(X?0===r:K.has(e.value)&&J.findIndex(e=>K.has(e.value))===r))})),A&&!J.length&&e.jsx(p.Text,{short:!0,children:"Ingen treff"})]}),E&&e.jsx(t.Button,{type:"button",variant:"primary",popovertarget:G,popovertargetaction:"hide",children:"Bekreft"})]}),e.jsxs("select",{defaultValue:!E&&void 0===D&&P?"":void 0,...z,tabIndex:-1,value:D,multiple:E,ref:_,"aria-labelledby":r.id,children:[!E&&P&&e.jsx("option",{value:"",disabled:!0,children:P}),W.map(o=>e.jsx("option",{value:o.value,children:o.label},o.value))]})]})})});b.displayName="Select",exports.Select=b;
|
|
2
2
|
//# sourceMappingURL=Select.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Select.cjs","sources":["../../../../src/components/select/Select.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport React, {\n type CSSProperties,\n type FocusEvent,\n forwardRef,\n type KeyboardEvent,\n type MouseEvent,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { useId } from \"../../hooks/useId/useId.js\";\nimport { useListNavigation } from \"../../hooks/useListNavigation/useListNavigation.js\";\nimport { usePreviousValue } from \"../../hooks/usePreviousValue/usePreviousValue.js\";\nimport { type ValuePair, getValuePair } from \"../../utilities/valuePair.js\";\nimport { ArrowVerticalAnimated } from \"../icon/icons/animated/ArrowVerticalAnimated.js\";\nimport { InputGroup } from \"../input-group/InputGroup.js\";\nimport Popover from \"../popover/Popover.js\";\nimport type { PopupTipProps } from \"../tooltip/types.js\";\nimport { focusSelected, toLower } from \"./select-utils.js\";\nimport type { SelectProps } from \"./types.js\";\n\nconst noop = () => {\n return;\n};\n\ninterface Option extends ValuePair {\n visible: boolean;\n}\n\nexport const Select = forwardRef<HTMLSelectElement, SelectProps>(\n (props, forwardedSelectRef) => {\n const {\n id,\n name,\n items,\n value,\n label,\n labelProps,\n onChange,\n onBlur,\n onFocus,\n className,\n helpLabel,\n errorLabel,\n invalid,\n searchable = false,\n inline = false,\n defaultPrompt = \"Velg\",\n width,\n maxShownOptions = 5,\n style,\n tooltip,\n \"data-testautoid\": dataTestAutoId,\n ...rest\n } = props;\n\n const listId = useId(id || \"jkl-select\", { generateSuffix: !id });\n const labelId = `${listId}_label`;\n const buttonId = `${listId}_button`;\n const searchInputId = `${listId}_search-input`;\n\n const [dropdownIsShown, setShown] = useState(false);\n const toggleListVisibility = useCallback(() => {\n setShown((previousValue) => !previousValue);\n }, []);\n\n // Lagrer faktisk placement etter at floating-ui har kjørt `flip`,\n // slik at vi kan bytte hvilken side av lista og knappen som er\n // flat når lista snus over triggeren.\n const [popoverPlacement, setPopoverPlacement] = useState<\n \"top\" | \"bottom\"\n >(\"bottom\");\n const handlePlacementChange = useCallback((p: string) => {\n setPopoverPlacement(p.startsWith(\"top\") ? \"top\" : \"bottom\");\n }, []);\n\n /// Søk\n\n const isSearchable = Boolean(searchable);\n const showSearchInputField = isSearchable && dropdownIsShown;\n const [searchValue, setSearchValue] = useState(\"\");\n const searchFn = useCallback(\n (item: ValuePair) => {\n if (\n item.label.toLowerCase().includes(searchValue.toLowerCase())\n ) {\n return true;\n }\n\n if (typeof searchable === \"function\") {\n return searchable(searchValue, item);\n }\n\n return false;\n },\n [searchable, searchValue],\n );\n const visibleItems: Option[] = useMemo(\n () =>\n items.map(getValuePair).map((item) => {\n const visible =\n !isSearchable || searchValue === \"\" || searchFn(item);\n return { ...item, visible };\n }),\n [items, isSearchable, searchValue, searchFn],\n );\n const valueIsInItems: boolean = useMemo(() => {\n if (typeof value === \"undefined\") {\n return false;\n }\n return items.some((item) =>\n typeof item === \"string\"\n ? item === value\n : item.value === value,\n );\n }, [value, items]);\n\n /// Valg av <option>\n\n const [selectedValue, setSelectedValue] = useState<string>(\n valueIsInItems && value !== undefined ? value : \"\",\n );\n const hasSelectedValue = selectedValue !== \"\";\n const selectedValueLabel = useMemo(\n () =>\n visibleItems.find((item) => item.value === selectedValue)\n ?.label || defaultPrompt,\n [visibleItems, selectedValue, defaultPrompt],\n );\n\n const selectRef = useRef<HTMLSelectElement | null>(null);\n // Hjelpefunksjon som gjør det enklere å forwarde refen og å bruke den selv internt\n const unifiedSelectRef = useCallback(\n (instance: HTMLSelectElement | null) => {\n selectRef.current = instance;\n if (forwardedSelectRef) {\n if (typeof forwardedSelectRef === \"function\") {\n forwardedSelectRef(instance);\n } else {\n forwardedSelectRef.current = instance;\n }\n }\n if (instance) {\n setSelectedValue(instance.value);\n }\n },\n [forwardedSelectRef],\n );\n\n const previousValue = usePreviousValue(value);\n useEffect(() => {\n if (value === previousValue) {\n return;\n }\n if (typeof value === \"undefined\" || !valueIsInItems) {\n setSelectedValue(\"\");\n } else {\n setSelectedValue(value);\n }\n }, [value, previousValue, valueIsInItems]);\n\n const selectOption = useCallback(\n (item: Option) => {\n const nextValue = item.value;\n setSearchValue(\"\");\n setSelectedValue(nextValue);\n toggleListVisibility();\n buttonRef.current?.focus();\n },\n [toggleListVisibility],\n );\n\n // La komponenten rendre <select> med den valgte verdien før onChange trigges, slik at\n // react-hook-form@>7.41.1 behandler feltet som at det har en verdi.\n const previousSelectedValue = usePreviousValue(selectedValue);\n useEffect(() => {\n // previousSelectedValue er undefined på første render, men da vil vi ikke ha en onChange uansett\n if (\n typeof previousSelectedValue === \"undefined\" ||\n previousSelectedValue === selectedValue ||\n selectedValue === value\n ) {\n return;\n }\n if (onChange) {\n onChange({\n type: \"change\",\n target: { name, value: selectedValue },\n });\n }\n if (selectRef.current) {\n selectRef.current.dispatchEvent(\n new Event(\"change\", { bubbles: true }),\n );\n }\n }, [onChange, name, value, selectedValue, previousSelectedValue]);\n\n /// Fokushåndtering\n\n const componentRootElementRef = useRef<HTMLDivElement>(null);\n const focusInsideRef = useRef(false);\n const searchFieldRef = useRef<HTMLInputElement>(null);\n const buttonRef = useRef<HTMLButtonElement>(null);\n\n const dropdownRef = useRef<HTMLDivElement | null>(null);\n // Lagrer listbox-elementet i state slik at downstream-hooks\n // (f.eks. `useListNavigation`) kan re-feste listeneren idet\n // `FloatingPortal` mounter listen.\n const [listboxEl, setListboxEl] = useState<HTMLDivElement | null>(null);\n\n // Listen rendres i en `FloatingPortal` som monteres via en\n // `useLayoutEffect` + `setState` i floating-ui. Refen er derfor\n // ikke tilgjengelig før i en senere render. Vi bruker en\n // callback-ref for å plassere fokus på valgt option idet listen\n // faktisk er i DOM-en. Refen holdes stabil (tom dependency-list)\n // slik at en endring i `selectedValue`/`isSearchable` ikke får\n // React til å avmontere/remontere refen og dermed flytte fokus\n // mens menyen er åpen — vi leser siste verdier via refs.\n const isSearchableRef = useRef(isSearchable);\n const selectedValueRef = useRef(selectedValue);\n useEffect(() => {\n isSearchableRef.current = isSearchable;\n selectedValueRef.current = selectedValue;\n });\n\n const setDropdownRef = useCallback((node: HTMLDivElement | null) => {\n dropdownRef.current = node;\n setListboxEl(node);\n if (node && !isSearchableRef.current) {\n // Popover skjules med `visibility: hidden` til\n // floating-ui har regnet ut første posisjon. Defer\n // fokus til etter neste paint, slik at vi ikke flytter\n // fokus til et usynlig element (kan gi manglende\n // fokusindikator i enkelte nettlesere).\n requestAnimationFrame(() => {\n if (dropdownRef.current === node) {\n focusSelected(node, selectedValueRef.current);\n }\n });\n }\n }, []);\n\n // Søkbart felt og knappen som får fokus ved lukking lever i hoved-\n // DOM-en, så for de tilfellene holder en useEffect.\n const wasShown = usePreviousValue(dropdownIsShown);\n useEffect(() => {\n if (dropdownIsShown === wasShown) return;\n if (dropdownIsShown && isSearchable) {\n searchFieldRef.current?.focus();\n } else if (\n !dropdownIsShown &&\n focusInsideRef.current &&\n buttonRef.current\n ) {\n buttonRef.current.focus();\n }\n }, [dropdownIsShown, wasShown, isSearchable]);\n\n useListNavigation({ element: listboxEl });\n\n const close = useCallback(() => {\n if (isSearchable) {\n setSearchValue(\"\");\n }\n if (onBlur) {\n onBlur({\n type: \"blur\",\n target: { name, value: selectedValue },\n });\n selectRef.current?.dispatchEvent(\n new Event(\"focusout\", { bubbles: true }),\n );\n }\n focusInsideRef.current = false;\n setShown(false);\n }, [onBlur, isSearchable, name, selectedValue]);\n\n const handleBlur = useCallback(\n (e: FocusEvent<HTMLButtonElement | HTMLInputElement>) => {\n const componentRootElement = componentRootElementRef.current;\n const dropdownElement = dropdownRef.current;\n // There are known issues in Firefox when using \"relatedTarget\" in onBlur events:\n // https://github.com/facebook/react/issues/2011\n // This might be fixed in react 17. Se issue above.\n // Dropdown rendres i en portal, så vi må sjekke begge trærne\n // for å avgjøre om fokus blir værende inne i komponenten.\n const nextFocusIsInsideComponent =\n componentRootElement?.contains(e.relatedTarget as Node) ||\n dropdownElement?.contains(e.relatedTarget as Node);\n if (!nextFocusIsInsideComponent) {\n close();\n }\n },\n [close],\n );\n\n const handleFocus = useCallback(() => {\n if (!focusInsideRef.current) {\n if (onFocus) {\n onFocus({\n type: \"change\",\n target: { name, value: selectedValue },\n });\n }\n focusInsideRef.current = true;\n }\n }, [onFocus, selectedValue, name]);\n\n const handleMouseOver = useCallback(\n (e: MouseEvent<HTMLButtonElement>) => {\n // Ved mouseOver på options flytter vi fokus til dem for å unngå \"dobbel fokus\"\n // der det ser ut som to forskjellige elementer er fokusert/hovered samtidig\n (e.target as HTMLButtonElement).focus({ preventScroll: true });\n },\n [],\n );\n\n // Handle focus and blur of hidden select element\n useEffect(() => {\n const select = selectRef.current;\n if (!select) return;\n\n const onSelectFocus = () => {\n if (showSearchInputField) {\n searchFieldRef.current?.focus();\n } else {\n buttonRef.current?.focus();\n }\n };\n const onSelectBlur = (ev: globalThis.FocusEvent) => {\n // Les refs ved hvert kall slik at vi alltid sjekker mot\n // siste listbox-element — den portalerte listen kan ha\n // mountet etter at denne effekten ble satt opp.\n const target = ev.relatedTarget as Node | null;\n const insideComponent =\n componentRootElementRef.current?.contains(target);\n const insideDropdown = dropdownRef.current?.contains(target);\n if (insideComponent || insideDropdown) {\n ev.preventDefault();\n }\n };\n\n select.addEventListener(\"focus\", onSelectFocus);\n select.addEventListener(\"blur\", onSelectBlur);\n return () => {\n select.removeEventListener(\"focus\", onSelectFocus);\n select.removeEventListener(\"blur\", onSelectBlur);\n };\n }, [showSearchInputField]);\n\n /// Tastaturnavigasjon\n\n // Add support for opening dropdown with arrowkey down as expected from native select\n // onKeyDown to stop ArrowDown from scrolling the page\n const handleOnKeyDown = useCallback(\n (e: KeyboardEvent<HTMLButtonElement>) => {\n if (\n (e.key === \"ArrowDown\" || e.key === \" \") &&\n !dropdownIsShown\n ) {\n e.preventDefault();\n e.stopPropagation();\n setShown(true);\n } else if (e.key === \"Escape\") {\n e.preventDefault();\n e.stopPropagation();\n setShown(false);\n }\n },\n [dropdownIsShown],\n );\n\n // onKeyDown to stop ArrowDown from scrolling the page\n const handleSearchOnKeyDown = useCallback(\n (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n e.stopPropagation();\n\n const listElement = dropdownRef.current;\n if (listElement) {\n if (isSearchable) {\n // Flytt fokus til det første elementet i listen, ikke det forrige valgte.\n // Ved endring i filter er det ikke gitt at vi ønsker å ta utgangspunkt i\n // den valgte verdien.\n focusSelected(listElement, undefined);\n } else {\n focusSelected(listElement, selectedValue);\n }\n }\n } else if (e.key === \"Escape\") {\n e.preventDefault();\n e.stopPropagation();\n setShown(false);\n } else if (e.key === \"Tab\" && !e.shiftKey) {\n const listElement = dropdownRef.current;\n if (listElement) {\n e.preventDefault();\n e.stopPropagation();\n focusSelected(listElement, selectedValue);\n }\n } else if (e.key === \"Enter\" && dropdownIsShown) {\n // Should not propagate Enter keyevent because form might submit\n e.preventDefault();\n e.stopPropagation();\n }\n },\n [selectedValue, isSearchable, dropdownIsShown],\n );\n\n // onKeyDown so this Tab listener isn't triggered by tabbing from search field to option\n const handleOptionOnKeyDown = useCallback(\n (e: KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === \"Tab\") {\n e.preventDefault();\n e.stopPropagation();\n\n if (e.shiftKey && searchFieldRef.current) {\n searchFieldRef.current.focus();\n } else if (buttonRef.current) {\n // Mimic behaviour of Firefox and native select, where Tab selects the current item and closes the menu\n setSelectedValue(e.currentTarget.value);\n setShown(false);\n buttonRef.current.focus();\n }\n } else if (e.key === \"ArrowUp\") {\n if (dropdownRef.current && searchFieldRef.current) {\n // Can't be based on index since the first item might be filtered out\n const firstVisible = dropdownRef.current.querySelector(\n '[role=\"option\"]:not([hidden])',\n );\n if (\n e.currentTarget.id === firstVisible?.id &&\n searchFieldRef.current\n ) {\n searchFieldRef.current.focus();\n }\n }\n }\n },\n [],\n );\n\n // Add support for closing the dropdown with Escape like native select. Unfortunately, Escape does not trigger the button onKeyDown.\n useEffect(() => {\n const handleEscape = (e: globalThis.KeyboardEvent) => {\n if (e.key === \"Escape\" && dropdownIsShown) {\n setShown(false);\n }\n };\n if (typeof window !== \"undefined\" && dropdownIsShown) {\n window.addEventListener(\"keydown\", handleEscape);\n }\n return () => {\n if (typeof window !== \"undefined\") {\n window.removeEventListener(\"keydown\", handleEscape);\n }\n };\n }, [dropdownIsShown]);\n\n return (\n <>\n <select\n name={name}\n tabIndex={-1}\n data-testid=\"jkl-native-select\"\n className=\"jkl-sr-only\"\n aria-hidden\n ref={unifiedSelectRef}\n value={selectedValue}\n onChange={noop} // React complains unless we give an onChange handler. This is technically a read-only field, but readOnly isn't an option here.\n >\n <option value=\"\" />{\" \"}\n {/* Tom option må være et valg, ellers vil <select> alltid ha en value */}\n {visibleItems.map((item) => (\n <option\n key={`${listId}-opt-${item.value}`}\n hidden={!item.visible}\n value={item.value}\n >\n {item.label}\n </option>\n ))}\n </select>\n <InputGroup\n ref={componentRootElementRef}\n data-testid=\"jkl-select\"\n className={clsx(\"jkl-select\", className, {\n \"jkl-select--inline\": inline,\n \"jkl-select--open\":\n dropdownIsShown &&\n visibleItems.some((item) => item.visible),\n \"jkl-select--no-value\": !hasSelectedValue,\n \"jkl-select--invalid\": !!errorLabel || invalid,\n })}\n data-testautoid={dataTestAutoId}\n tooltip={\n tooltip && React.isValidElement<PopupTipProps>(tooltip)\n ? React.cloneElement(tooltip, {\n triggerProps: {\n ...tooltip.props.triggerProps,\n onFocus: (\n e: FocusEvent<HTMLButtonElement>,\n ) => {\n tooltip.props.triggerProps?.onFocus?.(\n e,\n );\n close();\n },\n },\n })\n : null\n }\n {...rest}\n id={isSearchable ? searchInputId : buttonId}\n style={style}\n label={label}\n labelProps={{\n id: labelId,\n srOnly: inline,\n ...labelProps,\n htmlFor: isSearchable ? searchInputId : buttonId,\n }}\n helpLabel={helpLabel}\n errorLabel={errorLabel}\n render={({\n \"aria-invalid\": ariaInvalid,\n ...inputProps\n }) => {\n // Lista vises kun når dropdown er åpnet *og* det\n // finnes minst ett synlig valg. `aria-expanded` på\n // trigger og combobox må følge samme boolean for\n // ikke å lyve om popoverens tilstand.\n const isPopoverOpen =\n dropdownIsShown &&\n visibleItems.some((item) => item.visible);\n return (\n <Popover\n open={isPopoverOpen}\n placement=\"bottom-start\"\n offset={0}\n modal={false}\n onPlacementChange={handlePlacementChange}\n matchReferenceWidth\n clickOptions={{ enabled: false }}\n dismissOptions={{ enabled: false }}\n roleOptions={{ enabled: false }}\n >\n <Popover.Trigger asChild>\n <div\n className=\"jkl-select__outer-wrapper\"\n data-popover-placement={\n popoverPlacement\n }\n style={{ width }}\n >\n {isSearchable && (\n <input\n {...inputProps}\n aria-invalid={ariaInvalid}\n id={searchInputId}\n hidden={!showSearchInputField}\n ref={searchFieldRef}\n placeholder=\"Søk\"\n value={searchValue}\n onChange={(e) =>\n setSearchValue(\n e.target.value,\n )\n }\n data-testid=\"jkl-select__search-input\"\n className=\"jkl-select__search-input\"\n aria-autocomplete=\"list\"\n aria-activedescendant={\n isPopoverOpen &&\n hasSelectedValue\n ? `${listId}__${toLower(\n selectedValue,\n )}`\n : undefined\n }\n aria-controls={\n isPopoverOpen\n ? listId\n : undefined\n }\n aria-expanded={isPopoverOpen}\n role=\"combobox\"\n onKeyDown={\n handleSearchOnKeyDown\n }\n onBlur={handleBlur}\n onFocus={handleFocus}\n onClick={(e) => {\n e.stopPropagation();\n }}\n />\n )}\n {/* eslint-disable-next-line jsx-a11y/role-supports-aria-props */}\n <button\n // Nei dette er ikke i henhold til speccen, men VoiceOver leser den likevel og det er oppførselen vi ønsker\n aria-invalid={ariaInvalid}\n {...inputProps}\n id={buttonId}\n ref={buttonRef}\n hidden={showSearchInputField}\n type=\"button\"\n name={`${name}-btn`}\n className={clsx(\n \"jkl-select__button\",\n {\n \"jkl-select__button--active-value\":\n !!selectedValue,\n },\n )}\n data-testid=\"jkl-select__button\"\n aria-label={`${\n selectedValueLabel || \"Velg\"\n },${label}`}\n aria-expanded={isPopoverOpen}\n aria-controls={\n isPopoverOpen\n ? listId\n : undefined\n }\n onBlur={handleBlur}\n onFocus={handleFocus}\n onKeyDown={handleOnKeyDown}\n onClick={toggleListVisibility}\n onMouseDown={(e) => {\n // Workaround for en Safari-bug hvor e.relatedTarget er null i onBlur\n // https://twitter.com/MilesSorce/status/1278762360669265925\n e.preventDefault();\n buttonRef.current?.focus();\n }}\n >\n {selectedValueLabel}\n </button>\n <ArrowVerticalAnimated\n variant=\"medium\"\n pointingDown={!isPopoverOpen}\n className=\"jkl-select__arrow\"\n />\n </div>\n </Popover.Trigger>\n <Popover.Content\n initialFocus={-1}\n returnFocus={false}\n className=\"jkl-select__popover\"\n >\n <div\n id={listId}\n ref={setDropdownRef}\n // biome-ignore lint/a11y/useSemanticElements: Vi reimplementerer select\n role=\"listbox\"\n className=\"jkl-select__options-menu\"\n data-popover-placement={\n popoverPlacement\n }\n aria-labelledby={labelId}\n tabIndex={-1}\n data-testid=\"jkl-select__listbox\"\n data-testautoid={\n dataTestAutoId\n ? `${dataTestAutoId}__listbox`\n : \"jkl-select__listbox\"\n }\n data-focus=\"controlled\" // lar oss styre markering av valg vha focus\n style={\n {\n \"--jkl-select-max-shown-options\":\n maxShownOptions,\n } as CSSProperties\n }\n >\n {visibleItems.map((item, i) =>\n // Det er viktig at vi _fjerner_ elementer som ikke er synlige fra DOMen for at tastaturnavigasjon skal fungere.\n // For eksempel, hvis vi har elementene Apple, Samsung og LG i den rekkefølgen og søker etter \"l\"\n // vil Samsung ikke synes. Om vi bare setter hidden-attributtet på Samsung vil ArrowDown fra Apple ikke fungere.\n // Dette lar seg ikke gjenskape i en enhetstest med JSDOM + user-events, og Cypress lukker Select\n // ved første {downArrow} ¯\\_(ツ)_/¯. Så please test scenariet over manuelt om dette skaper trøbbel for deg.\n item.visible ? (\n <button\n key={`${listId}-${item.value}`}\n hidden={!item.visible}\n type=\"button\"\n id={`${listId}__${toLower(\n item.value,\n )}`}\n className=\"jkl-select__option\"\n data-testid=\"jkl-select__option\"\n aria-selected={\n item.value ===\n selectedValue\n }\n // biome-ignore lint/a11y/useSemanticElements: Vi reimplementerer select\n role=\"option\"\n value={item.value}\n data-testautoid={`jkl-select__option-${i}`}\n onBlur={handleBlur}\n onFocus={handleFocus}\n onKeyDown={\n handleOptionOnKeyDown\n }\n onClick={(e) => {\n e.preventDefault();\n selectOption(item);\n }}\n onMouseOver={\n handleMouseOver\n }\n >\n {item.label}\n {item.description ? (\n <span className=\"jkl-select__option-description\">\n {item.description}\n </span>\n ) : null}\n </button>\n ) : null,\n )}\n </div>\n </Popover.Content>\n </Popover>\n );\n }}\n />\n </>\n );\n },\n);\n\nSelect.displayName = \"Select\";\n"],"names":["noop","Select","forwardRef","props","forwardedSelectRef","id","name","items","value","label","labelProps","onChange","onBlur","onFocus","className","helpLabel","errorLabel","invalid","searchable","inline","defaultPrompt","width","maxShownOptions","style","tooltip","dataTestAutoId","rest","listId","useId","generateSuffix","labelId","buttonId","searchInputId","dropdownIsShown","setShown","useState","toggleListVisibility","useCallback","previousValue","popoverPlacement","setPopoverPlacement","handlePlacementChange","p","startsWith","isSearchable","showSearchInputField","searchValue","setSearchValue","searchFn","item","toLowerCase","includes","visibleItems","useMemo","map","getValuePair","visible","valueIsInItems","some","selectedValue","setSelectedValue","hasSelectedValue","selectedValueLabel","find","selectRef","useRef","unifiedSelectRef","instance","current","usePreviousValue","useEffect","selectOption","nextValue","buttonRef","focus","previousSelectedValue","type","target","dispatchEvent","Event","bubbles","componentRootElementRef","focusInsideRef","searchFieldRef","dropdownRef","listboxEl","setListboxEl","isSearchableRef","selectedValueRef","setDropdownRef","node","requestAnimationFrame","focusSelected","wasShown","useListNavigation","element","close","handleBlur","e","componentRootElement","dropdownElement","contains","relatedTarget","handleFocus","handleMouseOver","preventScroll","select","onSelectFocus","onSelectBlur","ev","insideComponent","insideDropdown","preventDefault","addEventListener","removeEventListener","handleOnKeyDown","key","stopPropagation","handleSearchOnKeyDown","listElement","shiftKey","handleOptionOnKeyDown","currentTarget","firstVisible","querySelector","handleEscape","window","jsxs","Fragment","children","tabIndex","ref","jsx","hidden","InputGroup","clsx","React","isValidElement","cloneElement","triggerProps","srOnly","htmlFor","render","ariaInvalid","inputProps","isPopoverOpen","Popover","open","placement","offset","modal","onPlacementChange","matchReferenceWidth","clickOptions","enabled","dismissOptions","roleOptions","Trigger","asChild","placeholder","toLower","role","onKeyDown","onClick","onMouseDown","ArrowVerticalAnimated","variant","pointingDown","Content","initialFocus","returnFocus","i","onMouseOver","description","displayName"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Select.cjs","sources":["../../../../src/components/select/Select.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport {\n type CSSProperties,\n type ComponentPropsWithoutRef,\n type KeyboardEvent,\n type FocusEvent,\n forwardRef,\n useId,\n useLayoutEffect,\n useRef,\n useState,\n} from \"react\";\nimport { useListNavigation } from \"../../hooks/index.js\";\nimport { mergeRefs } from \"../../utilities/mergeRefs.js\";\nimport { type ValuePair, getValuePair } from \"../../utilities/valuePair.js\";\nimport { Button } from \"../button/Button.js\";\nimport { Flex } from \"../flex/Flex.js\";\nimport { ArrowDownIcon, CloseIcon } from \"../icon/index.js\";\nimport { InputGroup } from \"../input-group/InputGroup.js\";\nimport type { InputGroupProps } from \"../input-group/types.js\";\nimport { Search } from \"../search/Search.js\";\nimport { Text } from \"../typography/Text.js\";\nimport { Title } from \"../typography/Title.js\";\nimport { Option } from \"./Option.js\";\nimport { autofocus, getButtonText, getReactNodeText } from \"./utils.js\";\nimport type { DataTestAutoId } from \"../../utilities/types.js\";\n\nexport type SelectProps = Omit<InputGroupProps, \"children\" | \"inline\"> &\n DataTestAutoId &\n Omit<ComponentPropsWithoutRef<\"select\">, \"size\" | \"children\"> & {\n width?: string;\n items: (string | ValuePair)[];\n placeholder?: string;\n } & (\n | {\n searchable: true;\n onSearch?: (searchTerm: string) => void;\n filterFunction?: (item: ValuePair, searchTerm: string) => boolean;\n }\n | {\n searchable?: false;\n onSearch?: never;\n filterFunction?: never;\n }\n );\n\nexport const Select = forwardRef<HTMLSelectElement, SelectProps>(\n function Select(props, externalRef) {\n const {\n label,\n errorLabel,\n helpLabel,\n labelProps,\n supportLabelProps,\n tooltip,\n description,\n style,\n className,\n id: idProp,\n items: rawItems,\n multiple = false,\n searchable = false,\n onSearch,\n filterFunction,\n placeholder,\n width,\n value,\n \"data-testautoid\": dataTestautoid,\n \"data-size\": size,\n ...elementProps\n } = props;\n\n const popoverRef = useRef<HTMLDivElement>(null);\n const selectRef = useRef<HTMLSelectElement>(null);\n const unifiedRef = mergeRefs(externalRef, selectRef);\n\n const baseId = `jkl-select-${useId()}`;\n const selectId = idProp ?? baseId;\n const popoverId = `${selectId}-popover`;\n\n const [filter, setFilter] = useState(\"\");\n const [selected, setSelected] = useState(() => new Set<string>());\n\n useListNavigation({ ref: popoverRef, disableTypeahead: searchable });\n\n const items = rawItems.map(getValuePair);\n const filteredItems =\n searchable && filter\n ? items.filter((item) =>\n filterFunction\n ? filterFunction(item, filter)\n : item.label\n .toLowerCase()\n .includes(filter.toLowerCase()),\n )\n : items;\n\n const showPlaceholder =\n selected.size === 0 || (selected.size === 1 && placeholder && selected.has(\"\"));\n const placeholderText = placeholder || \"Ingen valgt\";\n const buttonText = getButtonText(selected, items, placeholderText);\n\n /**\n * Setter event-lyttere for å synkronisere verdier i det skjulte select-elementet med\n * visningen i vår komponent, samt nullstilling av filter når menyen lukkes.\n */\n // biome-ignore lint/correctness/useExhaustiveDependencies:\n useLayoutEffect(() => {\n const select = selectRef.current;\n const popover = popoverRef.current;\n if (!select) return;\n\n const syncSelected = () => {\n setSelected(\n new Set(Array.from(select.selectedOptions, (o) => o.value)),\n );\n };\n\n const resetFilterOnClose = (event: ToggleEvent) => {\n if (event.newState === \"closed\") setFilter(\"\");\n };\n\n syncSelected();\n popover?.addEventListener(\"toggle\", resetFilterOnClose);\n select.addEventListener(\"change\", syncSelected);\n\n return () => {\n select.removeEventListener(\"change\", syncSelected);\n popover?.removeEventListener(\"toggle\", resetFilterOnClose);\n };\n }, [multiple, rawItems]);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: Oppdaterer visning når value settes\n useLayoutEffect(() => {\n setSelected(\n new Set(\n Array.from(\n selectRef.current?.selectedOptions ?? [],\n (o) => o.value,\n ),\n ),\n );\n }, [value, elementProps.defaultValue]);\n\n /**\n * Sørger for at menyen kan åpnes med piltastene slik som i native select\n */\n const openWithArrows = (event: KeyboardEvent) => {\n if (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n event.preventDefault();\n popoverRef.current?.showPopover?.();\n }\n };\n\n /**\n * Fyrer av focus- eller blur-event på det skjulte select-elementet når\n * fokus går inn eller ut av komponenten, slik at f.eks. react-hook-form\n * oppdaterer sin state riktig.\n */\n const syncFocus = (event: FocusEvent) => {\n const sel = selectRef.current;\n if (!popoverRef.current?.contains(event.relatedTarget)) {\n if (!sel) return;\n if ([\"focus\", \"focusin\"].includes(event.type)) {\n sel.dispatchEvent(new Event(\"focusin\", { bubbles: true }));\n sel.dispatchEvent(new Event(\"focus\", { bubbles: true }));\n } else if ([\"blur\", \"focusout\"].includes(event.type)) {\n sel.dispatchEvent(new Event(\"focusout\", { bubbles: true }));\n sel.dispatchEvent(new Event(\"blur\", { bubbles: true }));\n }\n }\n };\n\n return (\n <InputGroup\n id={selectId}\n label={label}\n errorLabel={errorLabel}\n helpLabel={helpLabel}\n labelProps={labelProps}\n supportLabelProps={supportLabelProps}\n tooltip={tooltip}\n description={description}\n style={style}\n data-testautoid={dataTestautoid}\n data-size={size}\n className={clsx(\"jkl-select\", className)}\n render={(inputProps) => (\n <>\n <button\n aria-label={`${showPlaceholder ? placeholderText : buttonText}, ${getReactNodeText(label)}`}\n className=\"jkl-select__button\"\n data-testid=\"jkl-select__button\"\n disabled={elementProps.disabled}\n type=\"button\"\n // @ts-ignore\n popovertarget={popoverId}\n style={{ \"--width\": width } as CSSProperties}\n onKeyDown={openWithArrows}\n onFocus={syncFocus}\n onBlur={syncFocus}\n {...inputProps}\n >\n {showPlaceholder ? placeholderText : buttonText}\n <ArrowDownIcon />\n </button>\n <Flex\n direction=\"column\"\n gap=\"16\"\n ref={popoverRef}\n // @ts-ignore\n popover=\"auto\"\n id={popoverId}\n className=\"jkl-select__popover\"\n aria-label={getReactNodeText(label)}\n >\n <Flex\n as=\"header\"\n alignItems=\"start\"\n justifyContent=\"space-between\"\n gap=\"8\"\n >\n <Title\n size=\"m\"\n as=\"h3\"\n id={`${selectId}-title`}\n >\n {label}\n </Title>\n <Button\n type=\"button\"\n variant=\"ghost\"\n icon={<CloseIcon />}\n aria-label=\"Lukk\"\n // @ts-ignore\n popovertarget={popoverId}\n popovertargetaction=\"hide\"\n />\n </Flex>\n {searchable && (\n <Search\n value={filter}\n onChange={(e) => {\n setFilter(e.target.value);\n onSearch?.(e.target.value);\n }}\n ref={autofocus(searchable)}\n autoComplete=\"off\"\n labelProps={{ srOnly: true }}\n label=\"Søk\"\n placeholder=\"Søk...\"\n width=\"100%\"\n className=\"jkl-spacing-8--bottom\"\n />\n )}\n <Flex\n direction=\"column\"\n gap=\"8\"\n // biome-ignore lint/a11y/useSemanticElements: Vi reimplementerer select\n role=\"listbox\"\n aria-multiselectable={multiple}\n aria-labelledby={`${selectId}-title`}\n >\n {filteredItems.map((pair, index) => (\n <Option\n {...pair}\n key={pair.value}\n selected={selected.has(pair.value)}\n multiple={multiple}\n selectRef={selectRef}\n // @ts-ignore\n popovertarget={\n multiple ? undefined : popoverId\n }\n popovertargetaction={\n multiple ? undefined : \"hide\"\n }\n ref={autofocus(() => {\n if (searchable) return false;\n if (showPlaceholder)\n return index === 0;\n return (\n selected.has(pair.value) &&\n filteredItems.findIndex((p) =>\n selected.has(p.value),\n ) === index\n );\n })}\n />\n ))}\n {searchable && !filteredItems.length && (\n <Text short>Ingen treff</Text>\n )}\n </Flex>\n {multiple && (\n <Button\n type=\"button\"\n variant=\"primary\"\n // @ts-ignore\n popovertarget={popoverId}\n popovertargetaction=\"hide\"\n >\n Bekreft\n </Button>\n )}\n </Flex>\n <select\n defaultValue={\n !multiple && value === undefined && placeholder\n ? \"\"\n : undefined\n }\n {...elementProps}\n tabIndex={-1}\n value={value}\n multiple={multiple}\n ref={unifiedRef}\n aria-labelledby={inputProps.id}\n >\n {!multiple && placeholder && (\n <option value=\"\" disabled>\n {placeholder}\n </option>\n )}\n {items.map((item) => (\n <option key={item.value} value={item.value}>\n {item.label}\n </option>\n ))}\n </select>\n </>\n )}\n />\n );\n },\n);\n\nSelect.displayName = \"Select\";\n"],"names":["Select","forwardRef","props","externalRef","label","errorLabel","helpLabel","labelProps","supportLabelProps","tooltip","description","style","className","id","idProp","items","rawItems","multiple","searchable","onSearch","filterFunction","placeholder","width","value","dataTestautoid","size","elementProps","popoverRef","useRef","selectRef","unifiedRef","mergeRefs","baseId","useId","selectId","popoverId","filter","setFilter","useState","selected","setSelected","Set","useListNavigation","ref","disableTypeahead","map","getValuePair","filteredItems","item","toLowerCase","includes","showPlaceholder","has","placeholderText","buttonText","getButtonText","useLayoutEffect","select","current","popover","syncSelected","Array","from","selectedOptions","o","resetFilterOnClose","event","newState","addEventListener","removeEventListener","defaultValue","openWithArrows","key","preventDefault","showPopover","syncFocus","sel","contains","relatedTarget","type","dispatchEvent","Event","bubbles","jsx","InputGroup","clsx","render","inputProps","jsxs","Fragment","children","getReactNodeText","disabled","popovertarget","onKeyDown","onFocus","onBlur","ArrowDownIcon","Flex","direction","gap","as","alignItems","justifyContent","Title","Button","variant","icon","CloseIcon","popovertargetaction","Search","onChange","e","target","autofocus","autoComplete","srOnly","role","pair","index","createElement","Option","findIndex","p","length","Text","short","tabIndex","displayName"],"mappings":"4rEA8CaA,EAASC,EAAAA,WAClB,SAAgBC,EAAOC,GACnB,MACIC,MAAAA,EACAC,WAAAA,EACAC,UAAAA,EACAC,WAAAA,EACAC,kBAAAA,EACAC,QAAAA,EACAC,YAAAA,EACAC,MAAAA,EACAC,UAAAA,EACAC,GAAIC,EACJC,MAAOC,EACPC,SAAAA,GAAW,EACXC,WAAAA,GAAa,EACbC,SAAAA,EACAC,eAAAA,EACAC,YAAAA,EACAC,MAAAA,EACAC,MAAAA,EACA,kBAAmBC,EACnB,YAAaC,KACVC,GACHxB,EAEEyB,EAAaC,EAAAA,OAAuB,MACpCC,EAAYD,EAAAA,OAA0B,MACtCE,EAAaC,EAAAA,UAAU5B,EAAa0B,GAEpCG,EAAS,cAAcC,EAAAA,UACvBC,EAAWpB,GAAUkB,EACrBG,EAAY,GAAGD,aAEdE,EAAQC,GAAaC,EAAAA,SAAS,KAC9BC,EAAUC,GAAeF,EAAAA,SAAS,IAAM,IAAIG,KAEnDC,EAAAA,kBAAkB,CAAEC,IAAKhB,EAAYiB,iBAAkB1B,IAEvD,MAAMH,EAAQC,EAAS6B,IAAIC,gBACrBC,EACF7B,GAAckB,EACRrB,EAAMqB,OAAQY,GACV5B,EACMA,EAAe4B,EAAMZ,GACrBY,EAAK5C,MACA6C,cACAC,SAASd,EAAOa,gBAE/BlC,EAEJoC,EACgB,IAAlBZ,EAASd,MAAiC,IAAlBc,EAASd,MAAcJ,GAAekB,EAASa,IAAI,IACzEC,EAAkBhC,GAAe,cACjCiC,EAAaC,EAAAA,cAAchB,EAAUxB,EAAOsC,GAOlDG,EAAAA,gBAAgB,KACZ,MAAMC,EAAS5B,EAAU6B,QACnBC,EAAUhC,EAAW+B,QAC3B,IAAKD,EAAQ,OAEb,MAAMG,EAAe,KACjBpB,EACI,IAAIC,IAAIoB,MAAMC,KAAKL,EAAOM,gBAAkBC,GAAMA,EAAEzC,UAItD0C,EAAsBC,IACD,WAAnBA,EAAMC,UAAuB9B,EAAU,KAG/C,OAAAuB,IACAD,GAASS,iBAAiB,SAAUH,GACpCR,EAAOW,iBAAiB,SAAUR,GAE3B,KACHH,EAAOY,oBAAoB,SAAUT,GACrCD,GAASU,oBAAoB,SAAUJ,KAE5C,CAAChD,EAAUD,IAGdwC,EAAAA,gBAAgB,KACZhB,EACI,IAAIC,IACAoB,MAAMC,KACFjC,EAAU6B,SAASK,iBAAmB,GACrCC,GAAMA,EAAEzC,UAItB,CAACA,EAAOG,EAAa4C,eAKxB,MAAMC,GAAkBL,KACF,cAAdA,EAAMM,KAAqC,YAAdN,EAAMM,OACnCN,EAAMO,iBACN9C,EAAW+B,SAASgB,kBAStBC,GAAaT,IACf,MAAMU,EAAM/C,EAAU6B,QACtB,IAAK/B,EAAW+B,SAASmB,SAASX,EAAMY,eAAgB,CACpD,IAAKF,EAAK,OACN,CAAC,QAAS,WAAW1B,SAASgB,EAAMa,OACpCH,EAAII,cAAc,IAAIC,MAAM,UAAW,CAAEC,SAAS,KAClDN,EAAII,cAAc,IAAIC,MAAM,QAAS,CAAEC,SAAS,MACzC,CAAC,OAAQ,YAAYhC,SAASgB,EAAMa,QAC3CH,EAAII,cAAc,IAAIC,MAAM,WAAY,CAAEC,SAAS,KACnDN,EAAII,cAAc,IAAIC,MAAM,OAAQ,CAAEC,SAAS,KAEvD,GAGJ,OACIC,EAAAA,IAACC,EAAAA,WAAA,CACGvE,GAAIqB,EACJ9B,MAAAA,EACAC,WAAAA,EACAC,UAAAA,EACAC,WAAAA,EACAC,kBAAAA,EACAC,QAAAA,EACAC,YAAAA,EACAC,MAAAA,EACA,kBAAiBa,EACjB,YAAWC,EACXb,UAAWyE,EAAAA,KAAK,aAAczE,GAC9B0E,OAASC,GACLC,EAAAA,KAAAC,EAAAA,SAAA,CACIC,SAAA,CAAAF,EAAAA,KAAC,SAAA,CACG,aAAY,GAAGrC,EAAkBE,EAAkBC,MAAeqC,EAAAA,iBAAiBvF,KACnFQ,UAAU,qBACV,cAAY,qBACZgF,SAAUlE,EAAakE,SACvBb,KAAK,SAELc,cAAe1D,EACfxB,MAAO,CAAE,UAAWW,GACpBwE,UAAWvB,GACXwB,QAASpB,GACTqB,OAAQrB,MACJY,EAEHG,SAAA,CAAAvC,EAAkBE,EAAkBC,QACpC2C,EAAAA,cAAA,CAAA,MAELT,EAAAA,KAACU,EAAAA,KAAA,CACGC,UAAU,SACVC,IAAI,KACJzD,IAAKhB,EAELgC,QAAQ,OACR9C,GAAIsB,EACJvB,UAAU,sBACV,aAAY+E,EAAAA,iBAAiBvF,GAE7BsF,SAAA,CAAAF,EAAAA,KAACU,EAAAA,KAAA,CACGG,GAAG,SACHC,WAAW,QACXC,eAAe,gBACfH,IAAI,IAEJV,SAAA,CAAAP,EAAAA,IAACqB,EAAAA,MAAA,CACG/E,KAAK,IACL4E,GAAG,KACHxF,GAAI,GAAGqB,UAENwD,SAAAtF,IAEL+E,EAAAA,IAACsB,EAAAA,OAAA,CACG1B,KAAK,SACL2B,QAAQ,QACRC,WAAOC,EAAAA,UAAA,IACP,aAAW,OAEXf,cAAe1D,EACf0E,oBAAoB,YAG3B3F,GACGiE,EAAAA,IAAC2B,EAAAA,OAAA,CACGvF,MAAOa,EACP2E,SAAWC,IACP3E,EAAU2E,EAAEC,OAAO1F,OACnBJ,IAAW6F,EAAEC,OAAO1F,QAExBoB,IAAKuE,EAAAA,UAAUhG,GACfiG,aAAa,MACb5G,WAAY,CAAE6G,QAAQ,GACtBhH,MAAM,MACNiB,YAAY,SACZC,MAAM,OACNV,UAAU,0BAGlB4E,EAAAA,KAACU,EAAAA,KAAA,CACGC,UAAU,SACVC,IAAI,IAEJiB,KAAK,UACL,uBAAsBpG,EACtB,kBAAiB,GAAGiB,UAEnBwD,SAAA,CAAA3C,EAAcF,IAAI,CAACyE,EAAMC,IACtBC,EAAAA,cAACC,EAAAA,OAAA,IACOH,EACJ9C,IAAK8C,EAAK/F,MACVgB,SAAUA,EAASa,IAAIkE,EAAK/F,OAC5BN,SAAAA,EACAY,UAAAA,EAEAgE,cACI5E,OAAW,EAAYkB,EAE3B0E,oBACI5F,OAAW,EAAY,OAE3B0B,IAAKuE,EAAAA,UAAU,KACPhG,IACAiC,EACiB,IAAVoE,EAEPhF,EAASa,IAAIkE,EAAK/F,QAClBwB,EAAc2E,UAAWC,GACrBpF,EAASa,IAAIuE,EAAEpG,UACbgG,OAKrBrG,IAAe6B,EAAc6E,cACzBC,OAAA,CAAKC,OAAK,EAACpC,SAAA,mBAGnBzE,GACGkE,EAAAA,IAACsB,EAAAA,OAAA,CACG1B,KAAK,SACL2B,QAAQ,UAERb,cAAe1D,EACf0E,oBAAoB,OACvBnB,SAAA,eAKTF,EAAAA,KAAC,SAAA,CACGlB,cACKrD,QAAsB,IAAVM,GAAuBF,EAC9B,QACA,KAENK,EACJqG,YACAxG,MAAAA,EACAN,SAAAA,EACA0B,IAAKb,EACL,kBAAiByD,EAAW1E,GAE3B6E,SAAA,EAACzE,GAAYI,GACV8D,EAAAA,IAAC,SAAA,CAAO5D,MAAM,GAAGqE,UAAQ,EACpBF,SAAArE,IAGRN,EAAM8B,IAAKG,GACRmC,EAAAA,IAAC,SAAA,CAAwB5D,MAAOyB,EAAKzB,MAChCmE,SAAA1C,EAAK5C,OADG4C,EAAKzB,eAS9C,GAGJvB,EAAOgI,YAAc"}
|
|
@@ -1,3 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
1
|
+
import { ComponentPropsWithoutRef } from 'react';
|
|
2
|
+
import { ValuePair } from '../../utilities/valuePair.cjs';
|
|
3
|
+
import { InputGroupProps } from '../input-group/types.cjs';
|
|
4
|
+
import { DataTestAutoId } from '../../utilities/types.cjs';
|
|
5
|
+
export type SelectProps = Omit<InputGroupProps, "children" | "inline"> & DataTestAutoId & Omit<ComponentPropsWithoutRef<"select">, "size" | "children"> & {
|
|
6
|
+
width?: string;
|
|
7
|
+
items: (string | ValuePair)[];
|
|
8
|
+
placeholder?: string;
|
|
9
|
+
} & ({
|
|
10
|
+
searchable: true;
|
|
11
|
+
onSearch?: (searchTerm: string) => void;
|
|
12
|
+
filterFunction?: (item: ValuePair, searchTerm: string) => boolean;
|
|
13
|
+
} | {
|
|
14
|
+
searchable?: false;
|
|
15
|
+
onSearch?: never;
|
|
16
|
+
filterFunction?: never;
|
|
17
|
+
});
|
|
18
|
+
export declare const Select: import('react').ForwardRefExoticComponent<SelectProps & import('react').RefAttributes<HTMLSelectElement>>;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./Select.cjs")
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./Select.cjs");exports.Select=e.Select;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1,5 +1 @@
|
|
|
1
|
-
export { Select } from './Select.cjs';
|
|
2
|
-
export { NativeSelect } from './NativeSelect.cjs';
|
|
3
|
-
export type { SelectProps, SelectChangeEventHandler, SelectPartialChangeEvent, NativeSelectProps, } from './types.cjs';
|
|
4
|
-
export { Select as BETA_Select } from '../beta/select/Select.jsx';
|
|
5
|
-
export type { SelectProps as BETA_SelectProps } from '../beta/select/types.cjs';
|
|
1
|
+
export { Select, type SelectProps } from './Select.cjs';
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react");exports.autofocus=e=>t=>{t&&(t.autofocus="boolean"==typeof e?e:e())},exports.getButtonText=(e,t,o)=>1===e.size?t.find(t=>e.has(t.value))?.label??o:`${e.size} valgt`,exports.getReactNodeText=function t(o){return"string"==typeof o||"number"==typeof o?String(o):Array.isArray(o)?o.map(t).join(""):e.isValidElement(o)?t(o.props.children):""};
|
|
2
|
+
//# sourceMappingURL=utils.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.cjs","sources":["../../../../src/components/select/utils.ts"],"sourcesContent":["import { type ReactNode, isValidElement } from \"react\";\nimport type { ValuePair } from \"../../utilities/valuePair.js\";\n\nexport function getReactNodeText(node: ReactNode): string {\n if (typeof node === \"string\" || typeof node === \"number\") return String(node);\n if (Array.isArray(node)) return node.map(getReactNodeText).join(\"\");\n if (isValidElement(node)) return getReactNodeText(node.props.children);\n return \"\";\n}\n\nexport const getButtonText = (\n selected: Set<string>,\n valuePairs: ValuePair[],\n placeholderText: string,\n): string => {\n if (selected.size === 1) {\n return (\n valuePairs.find((p) => selected.has(p.value))?.label ??\n placeholderText\n );\n }\n return `${selected.size} valgt`;\n};\n\nexport const autofocus =\n (active: boolean | (() => boolean)) => (el: HTMLElement | null) => {\n if (el) el.autofocus = typeof active === \"boolean\" ? active : active();\n };\n"],"names":["active","el","autofocus","selected","valuePairs","placeholderText","size","find","p","has","value","label","getReactNodeText","node","String","Array","isArray","map","join","isValidElement","props","children"],"mappings":"2HAyBKA,GAAuCC,IAChCA,IAAIA,EAAGC,UAA8B,kBAAXF,EAAuBA,EAASA,4BAhBzC,CACzBG,EACAC,EACAC,IAEsB,IAAlBF,EAASG,KAELF,EAAWG,KAAMC,GAAML,EAASM,IAAID,EAAEE,SAASC,OAC/CN,EAGD,GAAGF,EAASG,sCAlBhB,SAASM,EAAiBC,GAC7B,MAAoB,iBAATA,GAAqC,iBAATA,EAA0BC,OAAOD,GACpEE,MAAMC,QAAQH,GAAcA,EAAKI,IAAIL,GAAkBM,KAAK,IAC5DC,EAAAA,eAAeN,GAAcD,EAAiBC,EAAKO,MAAMC,UACtD,EACX"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { ValuePair } from '../../utilities/valuePair.cjs';
|
|
3
|
+
export declare function getReactNodeText(node: ReactNode): string;
|
|
4
|
+
export declare const getButtonText: (selected: Set<string>, valuePairs: ValuePair[], placeholderText: string) => string;
|
|
5
|
+
export declare const autofocus: (active: boolean | (() => boolean)) => (el: HTMLElement | null) => void;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),a=require("../../../clsx-E3yX_9sL.cjs"),i=require("react"),n=require("../../hooks/useId/useId.cjs"),t=require("../icon-button/IconButton.cjs"),l=require("../icon/icons/ChevronLeftIcon.cjs"),s=require("../icon/icons/ChevronRightIcon.cjs"),r=require("../select/
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),a=require("../../../clsx-E3yX_9sL.cjs"),i=require("react"),n=require("../../hooks/useId/useId.cjs"),t=require("../icon-button/IconButton.cjs"),l=require("../icon/icons/ChevronLeftIcon.cjs"),s=require("../icon/icons/ChevronRightIcon.cjs"),r=require("../select/Select.cjs"),c=require("../text-input/TextInput.cjs");const o=i.forwardRef((o,g)=>{const{activePage:j=0,totalNumberOfRows:p,rowsPerPage:b,rowsPerPageItems:d,className:m,id:h,withGoToPage:x=!1,onChange:k,onChangeRowsPerPage:_,labels:v={rowsPerPage:"Rader per side",previous:"Forrige",next:"Neste"},...C}=o,N=n.useId(h||"jkl-table-pagination",{generateSuffix:!h}),P=b<=0?1:Math.ceil(p/b),[f,I]=i.useState(function(e,a,i){return a<e?e:a>i?i:a}(0,j,P-1)),S=i.useCallback(e=>{const a=Number.parseInt(e.currentTarget.dataset.number);k(e,a,f),I(a),y(String(a+1))},[k,f]),[w,y]=i.useState(String(f+1)),q=i.useCallback(e=>{y(e.target.value);try{const a=Number.parseInt(e.target.value)-1;if(Number.isNaN(a))return;a>=0&&a<P&&(k(e,a,f),I(a))}catch{return}},[k,f,P]),A=i.useCallback(e=>{if(0===f)return void k(e,f,f);const a=f-1;k(e,a,f),I(a),y(String(a+1))},[k,f]),M=i.useCallback(e=>{if(f===P-1)return void k(e,f,f);const a=f+1;k(e,a,f),I(a),y(String(a+1))},[k,P,f]);return e.jsxs("div",{className:a.clsx("jkl-table-pagination",m),...C,id:N,ref:g,children:[e.jsx("div",{className:"jkl-table-pagination__left",children:e.jsxs("div",{className:"jkl-table-pagination__picker jkl-table-pagination__picker--rows",children:[e.jsxs("span",{className:"jkl-table-pagination__picker-label","aria-hidden":"true",children:[v.rowsPerPage,":"]}),e.jsx(r.Select,{className:"jkl-table-pagination__picker-input",label:v.rowsPerPage,labelProps:{srOnly:!0},name:`${N}-rows-per-page`,items:d.map(e=>"number"==typeof e?String(e):{label:e.label,value:String(e.value)}),value:String(b),onChange:_,width:"min(8rem, 100%)"})]})}),e.jsxs("span",{className:"jkl-table-pagination__total-rows",children:["Treff: ",p]}),e.jsx("div",{className:"jkl-table-pagination__right",children:1!==P&&e.jsxs("nav",{className:"jkl-table-pagination__nav",children:[x&&e.jsxs("div",{className:"jkl-table-pagination__picker jkl-table-pagination__picker--page",children:[e.jsxs("span",{className:"jkl-table-pagination__picker-label","aria-hidden":"true",children:["object"==typeof x?x.gotoLabel:"Gå til side",":"]}),e.jsx(c.TextInput,{className:"jkl-table-pagination__picker-input",label:"object"==typeof x?x.gotoLabel:"Gå til side",labelProps:{srOnly:!0},name:`${N}-go-to-page`,value:w,width:"min(4rem, 100%)",onChange:q,"aria-invalid":w&&w!==String(f+1)?"true":void 0})]}),e.jsxs("ul",{children:[e.jsx("li",{children:e.jsx(t.IconButton,{className:"jkl-table-pagination__previous",title:v.previous,onClick:A,children:e.jsx(l.ChevronLeftIcon,{})})}),e.jsx(u,{id:N,activePage:j,numberOfPages:P,onPageClick:S}),e.jsx("li",{children:e.jsx(t.IconButton,{className:"jkl-table-pagination__next",title:v.next,onClick:M,children:e.jsx(s.ChevronRightIcon,{})})})]})]})})]})}),u=({id:i,activePage:n,numberOfPages:t,onPageClick:l})=>{if(t<=7)return e.jsx(e.Fragment,{children:Array.from({length:t}).map((t,s)=>e.jsx("li",{children:e.jsx("button",{className:a.clsx("jkl-table-pagination__page",{"jkl-table-pagination__page--active":n===s}),type:"button","data-number":s,onClick:l,children:s+1})},`${i}-page-${s}`))});const s=n>3&&t>7,r=n<t-4&&t>7,c=Math.min(Math.max(n-2,1),t-6),o=Math.min(c+1,t-5),u=Math.min(o+1,t-4),j=Math.min(o+2,t-3),p=Math.min(o+3,t-2);return e.jsxs(e.Fragment,{children:[e.jsx("li",{children:e.jsx(g,{isActive:0===n,number:0,onClick:l})}),e.jsx("li",{children:s?e.jsx("span",{className:"jkl-table-pagination__ellipsis","aria-hidden":!0,children:"..."}):e.jsx(g,{isActive:n===c,number:c,onClick:l})}),e.jsx("li",{children:e.jsx(g,{isActive:n===o,number:o,onClick:l})}),e.jsx("li",{children:e.jsx(g,{isActive:n===u,number:u,onClick:l})}),e.jsx("li",{children:e.jsx(g,{isActive:n===j,number:j,onClick:l})}),e.jsx("li",{children:r?e.jsx("span",{className:"jkl-table-pagination__ellipsis","aria-hidden":!0,children:"..."}):e.jsx(g,{isActive:n===p,number:p,onClick:l})}),e.jsx("li",{children:e.jsx(g,{isActive:n===t-1,number:t-1,onClick:l})})]})},g=({isActive:i,number:n,onClick:t,...l})=>e.jsx("button",{className:a.clsx("jkl-table-pagination__page",{"jkl-table-pagination__page--active":i}),type:"button","data-number":n,onClick:t,...l,children:n+1});o.displayName="TablePagination",exports.TablePagination=o;
|
|
2
2
|
//# sourceMappingURL=TablePagination.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TablePagination.cjs","sources":["../../../../src/components/table/TablePagination.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport React, {\n forwardRef,\n useCallback,\n useState,\n type ChangeEventHandler,\n type FC,\n type MouseEventHandler,\n} from \"react\";\nimport { useId } from \"../../hooks/useId/useId.js\";\nimport { IconButton } from \"../icon-button/IconButton.js\";\nimport { ChevronLeftIcon } from \"../icon/icons/ChevronLeftIcon.js\";\nimport { ChevronRightIcon } from \"../icon/icons/ChevronRightIcon.js\";\nimport { NativeSelect } from \"../select/NativeSelect.js\";\nimport { TextInput } from \"../text-input/TextInput.js\";\nimport type { TablePaginationProps } from \"./types.js\";\n\nfunction clamp(min: number, num: number, max: number): number {\n if (num < min) {\n return min;\n }\n\n if (num > max) {\n return max;\n }\n\n return num;\n}\n\nexport const TablePagination = forwardRef<HTMLDivElement, TablePaginationProps>(\n (props, ref) => {\n const {\n activePage = 0,\n totalNumberOfRows,\n rowsPerPage,\n rowsPerPageItems,\n className,\n id: idProp,\n withGoToPage = false,\n onChange,\n onChangeRowsPerPage,\n labels = {\n rowsPerPage: \"Rader per side\",\n previous: \"Forrige\",\n next: \"Neste\",\n },\n ...rest\n } = props;\n\n const id = useId(idProp || \"jkl-table-pagination\", {\n generateSuffix: !idProp,\n });\n\n const showAll = rowsPerPage <= 0;\n const numberOfPages = showAll\n ? 1\n : Math.ceil(totalNumberOfRows / rowsPerPage);\n\n const [currentPage, setCurrentPage] = useState(\n clamp(0, activePage, numberOfPages - 1),\n );\n\n const onPageClick: MouseEventHandler<HTMLButtonElement> = useCallback(\n (e) => {\n const toPage = Number.parseInt(\n e.currentTarget.dataset.number as string,\n );\n onChange(e, toPage, currentPage);\n setCurrentPage(toPage);\n setPagePickerValue(String(toPage + 1));\n },\n [onChange, currentPage],\n );\n\n const [pagePickerValue, setPagePickerValue] = useState(\n String(currentPage + 1),\n );\n const onPageChange: ChangeEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n setPagePickerValue(e.target.value);\n try {\n const toPage = Number.parseInt(e.target.value) - 1;\n if (Number.isNaN(toPage)) {\n return;\n }\n\n if (toPage >= 0 && toPage < numberOfPages) {\n onChange(e, toPage, currentPage);\n setCurrentPage(toPage);\n }\n } catch {\n return;\n }\n },\n [onChange, currentPage, numberOfPages],\n );\n\n const onPrevious: MouseEventHandler<HTMLButtonElement> = useCallback(\n (e) => {\n if (currentPage === 0) {\n // TODO: skal dette være en no-op i stedet?\n onChange(e, currentPage, currentPage);\n return;\n }\n const toPage = currentPage - 1;\n onChange(e, toPage, currentPage);\n setCurrentPage(toPage);\n setPagePickerValue(String(toPage + 1));\n },\n [onChange, currentPage],\n );\n\n const onNext: MouseEventHandler<HTMLButtonElement> = useCallback(\n (e) => {\n if (currentPage === numberOfPages - 1) {\n // TODO: skal dette være en no-op i stedet?\n onChange(e, currentPage, currentPage);\n return;\n }\n const toPage = currentPage + 1;\n onChange(e, toPage, currentPage);\n setCurrentPage(toPage);\n setPagePickerValue(String(toPage + 1));\n },\n [onChange, numberOfPages, currentPage],\n );\n\n return (\n <div\n className={clsx(\"jkl-table-pagination\", className)}\n {...rest}\n id={id}\n ref={ref}\n >\n <div className=\"jkl-table-pagination__left\">\n <div className=\"jkl-table-pagination__picker jkl-table-pagination__picker--rows\">\n <span\n className=\"jkl-table-pagination__picker-label\"\n aria-hidden=\"true\"\n >\n {labels.rowsPerPage}:\n </span>\n <NativeSelect\n className=\"jkl-table-pagination__picker-input\"\n label={labels.rowsPerPage}\n labelProps={{ srOnly: true }}\n name={`${id}-rows-per-page`}\n items={rowsPerPageItems.map((i) =>\n typeof i === \"number\"\n ? String(i)\n : {\n label: i.label,\n value: String(i.value),\n },\n )}\n value={String(rowsPerPage)}\n onChange={onChangeRowsPerPage}\n width=\"min(8rem, 100%)\"\n inline\n />\n </div>\n </div>\n <span className=\"jkl-table-pagination__total-rows\">\n Treff: {totalNumberOfRows}\n </span>\n <div className=\"jkl-table-pagination__right\">\n {numberOfPages !== 1 && (\n <nav className=\"jkl-table-pagination__nav\">\n {withGoToPage && (\n <div className=\"jkl-table-pagination__picker jkl-table-pagination__picker--page\">\n <span\n className=\"jkl-table-pagination__picker-label\"\n aria-hidden=\"true\"\n >\n {typeof withGoToPage === \"object\"\n ? withGoToPage.gotoLabel\n : \"Gå til side\"}\n :\n </span>\n {/* onChange først ved enter/submit */}\n <TextInput\n className=\"jkl-table-pagination__picker-input\"\n label={\n typeof withGoToPage === \"object\"\n ? withGoToPage.gotoLabel\n : \"Gå til side\"\n }\n labelProps={{ srOnly: true }}\n name={`${id}-go-to-page`}\n value={pagePickerValue}\n width=\"min(4rem, 100%)\"\n onChange={onPageChange}\n aria-invalid={\n pagePickerValue &&\n pagePickerValue !==\n String(currentPage + 1)\n ? \"true\"\n : undefined\n }\n />\n </div>\n )}\n <ul>\n <li>\n <IconButton\n className=\"jkl-table-pagination__previous\"\n title={labels.previous}\n onClick={onPrevious}\n >\n <ChevronLeftIcon />\n </IconButton>\n </li>\n <PaginationPages\n id={id}\n activePage={activePage}\n numberOfPages={numberOfPages}\n onPageClick={onPageClick}\n />\n <li>\n <IconButton\n className=\"jkl-table-pagination__next\"\n title={labels.next}\n onClick={onNext}\n >\n <ChevronRightIcon />\n </IconButton>\n </li>\n </ul>\n </nav>\n )}\n </div>\n </div>\n );\n },\n);\n\nconst PaginationPages: FC<{\n id: string;\n activePage: number;\n numberOfPages: number;\n onPageClick: MouseEventHandler;\n}> = ({ id, activePage, numberOfPages, onPageClick }) => {\n if (numberOfPages <= 7) {\n return (\n <>\n {Array.from({ length: numberOfPages }).map((_, i) => (\n <li key={`${id}-page-${i}`}>\n <button\n className={clsx(\"jkl-table-pagination__page\", {\n \"jkl-table-pagination__page--active\":\n activePage === i,\n })}\n type=\"button\"\n data-number={i}\n onClick={onPageClick}\n >\n {i + 1}\n </button>\n </li>\n ))}\n </>\n );\n }\n\n const showStartEllipsis = activePage > 3 && numberOfPages > 7;\n const showEndEllipsis = activePage < numberOfPages - 4 && numberOfPages > 7;\n\n const startEllipsis = Math.min(\n Math.max(activePage - 2, 1),\n numberOfPages - 6,\n );\n const centerPageNumberStart = Math.min(\n startEllipsis + 1,\n numberOfPages - 5,\n );\n const centerPageNumber = Math.min(\n centerPageNumberStart + 1,\n numberOfPages - 4,\n );\n const centerPageNumberEnd = Math.min(\n centerPageNumberStart + 2,\n numberOfPages - 3,\n );\n const endEllipsis = Math.min(centerPageNumberStart + 3, numberOfPages - 2);\n\n return (\n <>\n <li>\n <PaginationPageButton\n isActive={activePage === 0}\n number={0}\n onClick={onPageClick}\n />\n </li>\n <li>\n {showStartEllipsis ? (\n <span\n className=\"jkl-table-pagination__ellipsis\"\n aria-hidden\n >\n {\"...\"}\n </span>\n ) : (\n <PaginationPageButton\n isActive={activePage === startEllipsis}\n number={startEllipsis}\n onClick={onPageClick}\n />\n )}\n </li>\n <li>\n <PaginationPageButton\n isActive={activePage === centerPageNumberStart}\n number={centerPageNumberStart}\n onClick={onPageClick}\n />\n </li>\n <li>\n <PaginationPageButton\n isActive={activePage === centerPageNumber}\n number={centerPageNumber}\n onClick={onPageClick}\n />\n </li>\n <li>\n <PaginationPageButton\n isActive={activePage === centerPageNumberEnd}\n number={centerPageNumberEnd}\n onClick={onPageClick}\n />\n </li>\n <li>\n {showEndEllipsis ? (\n <span\n className=\"jkl-table-pagination__ellipsis\"\n aria-hidden\n >\n {\"...\"}\n </span>\n ) : (\n <PaginationPageButton\n isActive={activePage === endEllipsis}\n number={endEllipsis}\n onClick={onPageClick}\n />\n )}\n </li>\n <li>\n <PaginationPageButton\n isActive={activePage === numberOfPages - 1}\n number={numberOfPages - 1}\n onClick={onPageClick}\n />\n </li>\n </>\n );\n};\n\nconst PaginationPageButton: FC<{\n isActive: boolean;\n number: number;\n onClick: MouseEventHandler;\n}> = ({ isActive, number, onClick, ...rest }) => (\n <button\n className={clsx(\"jkl-table-pagination__page\", {\n \"jkl-table-pagination__page--active\": isActive,\n })}\n type=\"button\"\n data-number={number}\n onClick={onClick}\n {...rest}\n >\n {number + 1}\n </button>\n);\n\nTablePagination.displayName = \"TablePagination\";\n"],"names":["TablePagination","forwardRef","props","ref","activePage","totalNumberOfRows","rowsPerPage","rowsPerPageItems","className","id","idProp","withGoToPage","onChange","onChangeRowsPerPage","labels","previous","next","rest","useId","generateSuffix","numberOfPages","Math","ceil","currentPage","setCurrentPage","useState","min","num","max","clamp","onPageClick","useCallback","e","toPage","Number","parseInt","currentTarget","dataset","number","setPagePickerValue","String","pagePickerValue","onPageChange","target","value","isNaN","onPrevious","onNext","jsxs","clsx","children","jsx","NativeSelect","label","labelProps","srOnly","name","items","map","i","width","inline","gotoLabel","TextInput","IconButton","title","onClick","ChevronLeftIcon","PaginationPages","ChevronRightIcon","Fragment","Array","from","length","_","type","showStartEllipsis","showEndEllipsis","startEllipsis","centerPageNumberStart","centerPageNumber","centerPageNumberEnd","endEllipsis","PaginationPageButton","isActive","displayName"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TablePagination.cjs","sources":["../../../../src/components/table/TablePagination.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport React, {\n forwardRef,\n useCallback,\n useState,\n type ChangeEventHandler,\n type FC,\n type MouseEventHandler,\n} from \"react\";\nimport { useId } from \"../../hooks/useId/useId.js\";\nimport { IconButton } from \"../icon-button/IconButton.js\";\nimport { ChevronLeftIcon } from \"../icon/icons/ChevronLeftIcon.js\";\nimport { ChevronRightIcon } from \"../icon/icons/ChevronRightIcon.js\";\nimport { Select } from \"../select/Select.js\";\nimport { TextInput } from \"../text-input/TextInput.js\";\nimport type { TablePaginationProps } from \"./types.js\";\n\nfunction clamp(min: number, num: number, max: number): number {\n if (num < min) {\n return min;\n }\n\n if (num > max) {\n return max;\n }\n\n return num;\n}\n\nexport const TablePagination = forwardRef<HTMLDivElement, TablePaginationProps>(\n (props, ref) => {\n const {\n activePage = 0,\n totalNumberOfRows,\n rowsPerPage,\n rowsPerPageItems,\n className,\n id: idProp,\n withGoToPage = false,\n onChange,\n onChangeRowsPerPage,\n labels = {\n rowsPerPage: \"Rader per side\",\n previous: \"Forrige\",\n next: \"Neste\",\n },\n ...rest\n } = props;\n\n const id = useId(idProp || \"jkl-table-pagination\", {\n generateSuffix: !idProp,\n });\n\n const showAll = rowsPerPage <= 0;\n const numberOfPages = showAll\n ? 1\n : Math.ceil(totalNumberOfRows / rowsPerPage);\n\n const [currentPage, setCurrentPage] = useState(\n clamp(0, activePage, numberOfPages - 1),\n );\n\n const onPageClick: MouseEventHandler<HTMLButtonElement> = useCallback(\n (e) => {\n const toPage = Number.parseInt(\n e.currentTarget.dataset.number as string,\n );\n onChange(e, toPage, currentPage);\n setCurrentPage(toPage);\n setPagePickerValue(String(toPage + 1));\n },\n [onChange, currentPage],\n );\n\n const [pagePickerValue, setPagePickerValue] = useState(\n String(currentPage + 1),\n );\n const onPageChange: ChangeEventHandler<HTMLInputElement> = useCallback(\n (e) => {\n setPagePickerValue(e.target.value);\n try {\n const toPage = Number.parseInt(e.target.value) - 1;\n if (Number.isNaN(toPage)) {\n return;\n }\n\n if (toPage >= 0 && toPage < numberOfPages) {\n onChange(e, toPage, currentPage);\n setCurrentPage(toPage);\n }\n } catch {\n return;\n }\n },\n [onChange, currentPage, numberOfPages],\n );\n\n const onPrevious: MouseEventHandler<HTMLButtonElement> = useCallback(\n (e) => {\n if (currentPage === 0) {\n // TODO: skal dette være en no-op i stedet?\n onChange(e, currentPage, currentPage);\n return;\n }\n const toPage = currentPage - 1;\n onChange(e, toPage, currentPage);\n setCurrentPage(toPage);\n setPagePickerValue(String(toPage + 1));\n },\n [onChange, currentPage],\n );\n\n const onNext: MouseEventHandler<HTMLButtonElement> = useCallback(\n (e) => {\n if (currentPage === numberOfPages - 1) {\n // TODO: skal dette være en no-op i stedet?\n onChange(e, currentPage, currentPage);\n return;\n }\n const toPage = currentPage + 1;\n onChange(e, toPage, currentPage);\n setCurrentPage(toPage);\n setPagePickerValue(String(toPage + 1));\n },\n [onChange, numberOfPages, currentPage],\n );\n\n return (\n <div\n className={clsx(\"jkl-table-pagination\", className)}\n {...rest}\n id={id}\n ref={ref}\n >\n <div className=\"jkl-table-pagination__left\">\n <div className=\"jkl-table-pagination__picker jkl-table-pagination__picker--rows\">\n <span\n className=\"jkl-table-pagination__picker-label\"\n aria-hidden=\"true\"\n >\n {labels.rowsPerPage}:\n </span>\n <Select\n className=\"jkl-table-pagination__picker-input\"\n label={labels.rowsPerPage}\n labelProps={{ srOnly: true }}\n name={`${id}-rows-per-page`}\n items={rowsPerPageItems.map((i) =>\n typeof i === \"number\"\n ? String(i)\n : {\n label: i.label,\n value: String(i.value),\n },\n )}\n value={String(rowsPerPage)}\n onChange={onChangeRowsPerPage}\n width=\"min(8rem, 100%)\"\n />\n </div>\n </div>\n <span className=\"jkl-table-pagination__total-rows\">\n Treff: {totalNumberOfRows}\n </span>\n <div className=\"jkl-table-pagination__right\">\n {numberOfPages !== 1 && (\n <nav className=\"jkl-table-pagination__nav\">\n {withGoToPage && (\n <div className=\"jkl-table-pagination__picker jkl-table-pagination__picker--page\">\n <span\n className=\"jkl-table-pagination__picker-label\"\n aria-hidden=\"true\"\n >\n {typeof withGoToPage === \"object\"\n ? withGoToPage.gotoLabel\n : \"Gå til side\"}\n :\n </span>\n {/* onChange først ved enter/submit */}\n <TextInput\n className=\"jkl-table-pagination__picker-input\"\n label={\n typeof withGoToPage === \"object\"\n ? withGoToPage.gotoLabel\n : \"Gå til side\"\n }\n labelProps={{ srOnly: true }}\n name={`${id}-go-to-page`}\n value={pagePickerValue}\n width=\"min(4rem, 100%)\"\n onChange={onPageChange}\n aria-invalid={\n pagePickerValue &&\n pagePickerValue !==\n String(currentPage + 1)\n ? \"true\"\n : undefined\n }\n />\n </div>\n )}\n <ul>\n <li>\n <IconButton\n className=\"jkl-table-pagination__previous\"\n title={labels.previous}\n onClick={onPrevious}\n >\n <ChevronLeftIcon />\n </IconButton>\n </li>\n <PaginationPages\n id={id}\n activePage={activePage}\n numberOfPages={numberOfPages}\n onPageClick={onPageClick}\n />\n <li>\n <IconButton\n className=\"jkl-table-pagination__next\"\n title={labels.next}\n onClick={onNext}\n >\n <ChevronRightIcon />\n </IconButton>\n </li>\n </ul>\n </nav>\n )}\n </div>\n </div>\n );\n },\n);\n\nconst PaginationPages: FC<{\n id: string;\n activePage: number;\n numberOfPages: number;\n onPageClick: MouseEventHandler;\n}> = ({ id, activePage, numberOfPages, onPageClick }) => {\n if (numberOfPages <= 7) {\n return (\n <>\n {Array.from({ length: numberOfPages }).map((_, i) => (\n <li key={`${id}-page-${i}`}>\n <button\n className={clsx(\"jkl-table-pagination__page\", {\n \"jkl-table-pagination__page--active\":\n activePage === i,\n })}\n type=\"button\"\n data-number={i}\n onClick={onPageClick}\n >\n {i + 1}\n </button>\n </li>\n ))}\n </>\n );\n }\n\n const showStartEllipsis = activePage > 3 && numberOfPages > 7;\n const showEndEllipsis = activePage < numberOfPages - 4 && numberOfPages > 7;\n\n const startEllipsis = Math.min(\n Math.max(activePage - 2, 1),\n numberOfPages - 6,\n );\n const centerPageNumberStart = Math.min(\n startEllipsis + 1,\n numberOfPages - 5,\n );\n const centerPageNumber = Math.min(\n centerPageNumberStart + 1,\n numberOfPages - 4,\n );\n const centerPageNumberEnd = Math.min(\n centerPageNumberStart + 2,\n numberOfPages - 3,\n );\n const endEllipsis = Math.min(centerPageNumberStart + 3, numberOfPages - 2);\n\n return (\n <>\n <li>\n <PaginationPageButton\n isActive={activePage === 0}\n number={0}\n onClick={onPageClick}\n />\n </li>\n <li>\n {showStartEllipsis ? (\n <span\n className=\"jkl-table-pagination__ellipsis\"\n aria-hidden\n >\n {\"...\"}\n </span>\n ) : (\n <PaginationPageButton\n isActive={activePage === startEllipsis}\n number={startEllipsis}\n onClick={onPageClick}\n />\n )}\n </li>\n <li>\n <PaginationPageButton\n isActive={activePage === centerPageNumberStart}\n number={centerPageNumberStart}\n onClick={onPageClick}\n />\n </li>\n <li>\n <PaginationPageButton\n isActive={activePage === centerPageNumber}\n number={centerPageNumber}\n onClick={onPageClick}\n />\n </li>\n <li>\n <PaginationPageButton\n isActive={activePage === centerPageNumberEnd}\n number={centerPageNumberEnd}\n onClick={onPageClick}\n />\n </li>\n <li>\n {showEndEllipsis ? (\n <span\n className=\"jkl-table-pagination__ellipsis\"\n aria-hidden\n >\n {\"...\"}\n </span>\n ) : (\n <PaginationPageButton\n isActive={activePage === endEllipsis}\n number={endEllipsis}\n onClick={onPageClick}\n />\n )}\n </li>\n <li>\n <PaginationPageButton\n isActive={activePage === numberOfPages - 1}\n number={numberOfPages - 1}\n onClick={onPageClick}\n />\n </li>\n </>\n );\n};\n\nconst PaginationPageButton: FC<{\n isActive: boolean;\n number: number;\n onClick: MouseEventHandler;\n}> = ({ isActive, number, onClick, ...rest }) => (\n <button\n className={clsx(\"jkl-table-pagination__page\", {\n \"jkl-table-pagination__page--active\": isActive,\n })}\n type=\"button\"\n data-number={number}\n onClick={onClick}\n {...rest}\n >\n {number + 1}\n </button>\n);\n\nTablePagination.displayName = \"TablePagination\";\n"],"names":["TablePagination","forwardRef","props","ref","activePage","totalNumberOfRows","rowsPerPage","rowsPerPageItems","className","id","idProp","withGoToPage","onChange","onChangeRowsPerPage","labels","previous","next","rest","useId","generateSuffix","numberOfPages","Math","ceil","currentPage","setCurrentPage","useState","min","num","max","clamp","onPageClick","useCallback","e","toPage","Number","parseInt","currentTarget","dataset","number","setPagePickerValue","String","pagePickerValue","onPageChange","target","value","isNaN","onPrevious","onNext","jsxs","clsx","children","jsx","Select","label","labelProps","srOnly","name","items","map","i","width","gotoLabel","TextInput","IconButton","title","onClick","ChevronLeftIcon","PaginationPages","ChevronRightIcon","Fragment","Array","from","length","_","type","showStartEllipsis","showEndEllipsis","startEllipsis","centerPageNumberStart","centerPageNumber","centerPageNumberEnd","endEllipsis","PaginationPageButton","isActive","displayName"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tabs.cjs","sources":["../../../../../../node_modules/.pnpm/nanoid@
|
|
1
|
+
{"version":3,"file":"Tabs.cjs","sources":["../../../../../../node_modules/.pnpm/nanoid@6.0.1/node_modules/nanoid/url-alphabet/index.js","../../../../../../node_modules/.pnpm/nanoid@6.0.1/node_modules/nanoid/index.browser.js","../../../../src/components/tabs/Tabs.tsx"],"sourcesContent":["export let urlAlphabet =\n 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'\n","\n\nimport { urlAlphabet } from './url-alphabet/index.js'\n\nexport { urlAlphabet }\n\nexport let random = bytes => crypto.getRandomValues(new Uint8Array(bytes))\n\nexport let customRandom = (alphabet, defaultSize, getRandom) => {\n let safeByteCutoff = 256 - (256 % alphabet.length)\n\n if (safeByteCutoff === 256) {\n let mask = alphabet.length - 1\n\n return (size = defaultSize) => {\n if (!size) return ''\n let id = ''\n while (true) {\n let bytes = getRandom(size)\n let j = size\n while (j--) {\n id += alphabet[bytes[j] & mask]\n if (id.length >= size) return id\n }\n }\n }\n }\n\n let step = Math.ceil((1.6 * 256 * defaultSize) / safeByteCutoff)\n\n return (size = defaultSize) => {\n if (!size) return ''\n let id = ''\n while (true) {\n let bytes = getRandom(step)\n let j = step\n while (j--) {\n if (bytes[j] < safeByteCutoff) {\n id += alphabet[bytes[j] % alphabet.length]\n if (id.length >= size) return id\n }\n }\n }\n }\n}\n\nexport let customAlphabet = (alphabet, size = 21) =>\n customRandom(alphabet, size | 0, random)\n\nexport let nanoid = (size = 21) => {\n let id = ''\n let bytes = crypto.getRandomValues(new Uint8Array((size |= 0)))\n while (size--) {\n id += urlAlphabet[bytes[size] & 63]\n }\n return id\n}\n","import clsx from \"clsx\";\nimport { nanoid } from \"nanoid\";\nimport React, { useCallback, useEffect, useState } from \"react\";\nimport { usePreviousValue } from \"../../hooks/usePreviousValue/usePreviousValue.js\";\nimport type { InjectedProps } from \"./TabList.js\";\nimport type { TabListProps, TabPanelProps, TabsProps } from \"./types.js\";\n\n/**\n * Konteiner for et grensesnitt hvor man kan tabbe mellom innhold.\n * Må inneholde en TabList etterfulgt av en eller flere TabPanel.\n *\n * Docs: https://jokul.fremtind.no/komponenter/tabs\n */\nexport const Tabs = ({ onChange, defaultTab, ...props }: TabsProps) => {\n const [activeIndex, setActiveIndex] = useState(defaultTab ?? 0);\n\n const previousTabIndex = usePreviousValue(activeIndex);\n\n useEffect(() => {\n if (\n previousTabIndex !== undefined &&\n previousTabIndex !== activeIndex &&\n onChange\n ) {\n onChange(activeIndex);\n }\n }, [onChange, previousTabIndex, activeIndex]);\n\n const [tabIDs, setTabIDs] = useState<string[]>([]);\n const [tabPanelIDs, setTabPanelIds] = useState<string[]>([]);\n\n const resolveIDs = useCallback(() => {\n const tabList = React.Children.toArray(props.children)[0];\n\n if (!React.isValidElement(tabList)) return;\n\n React.Children.forEach(tabList.props.children, (tab) => {\n if (!React.isValidElement(tab)) return;\n\n setTabIDs((prev) => [...prev, `jkl-tab-${nanoid(8)}`]);\n setTabPanelIds((prev) => [...prev, `jkl-tabpanel-${nanoid(8)}`]);\n });\n }, [props.children]);\n\n const renderTabList = () => {\n const tabList = React.Children.toArray(props.children)[0];\n\n if (!React.isValidElement<TabListProps & InjectedProps>(tabList))\n return;\n\n return React.cloneElement<TabListProps & InjectedProps>(tabList, {\n activeIndex,\n setActiveIndex,\n tabIDs,\n tabPanelIDs,\n });\n };\n\n const renderTabPanels = () => {\n return React.Children.map(props.children, (child, childIndex) => {\n if (\n !React.isValidElement<\n TabPanelProps & React.HTMLAttributes<HTMLDivElement>\n >(child) ||\n childIndex === 0\n )\n return;\n\n const tabPanelIndex = childIndex - 1;\n\n return tabPanelIndex === activeIndex\n ? React.cloneElement<\n TabPanelProps & React.HTMLAttributes<HTMLDivElement>\n >(child, {\n \"aria-labelledby\": tabIDs[tabPanelIndex],\n id: tabPanelIDs[tabPanelIndex],\n })\n : null;\n });\n };\n\n useEffect(() => {\n resolveIDs();\n }, [resolveIDs]);\n\n return (\n <div {...props} className={clsx(\"jkl-tabs\", props.className)}>\n {renderTabList()}\n {renderTabPanels()}\n </div>\n );\n};\n"],"names":["nanoid","size","id","bytes","crypto","getRandomValues","Uint8Array","onChange","defaultTab","props","activeIndex","setActiveIndex","useState","previousTabIndex","usePreviousValue","useEffect","tabIDs","setTabIDs","tabPanelIDs","setTabPanelIds","resolveIDs","useCallback","tabList","React","Children","toArray","children","isValidElement","forEach","tab","prev","jsxs","className","clsx","cloneElement","renderTabList","map","child","childIndex","tabPanelIndex"],"mappings":"+OAAO,ICiDIA,EAAS,CAACC,EAAO,MAC1B,IAAIC,EAAK,GACLC,EAAQC,OAAOC,gBAAgB,IAAIC,WAAYL,GAAQ,IAC3D,KAAOA,KACLC,GDpDF,mECoDkC,GAAdC,EAAMF,IAE1B,OAAOC,gBC1CW,EAAGK,SAAAA,EAAUC,WAAAA,KAAeC,MAC5C,MAAOC,EAAaC,GAAkBC,EAAAA,SAASJ,GAAc,GAEvDK,EAAmBC,EAAAA,iBAAiBJ,GAE1CK,EAAAA,UAAU,UAEmB,IAArBF,GACAA,IAAqBH,GACrBH,GAEAA,EAASG,IAEd,CAACH,EAAUM,EAAkBH,IAEhC,MAAOM,EAAQC,GAAaL,EAAAA,SAAmB,KACxCM,EAAaC,GAAkBP,EAAAA,SAAmB,IAEnDQ,EAAaC,EAAAA,YAAY,KAC3B,MAAMC,EAAUC,EAAMC,SAASC,QAAQhB,EAAMiB,UAAU,GAElDH,EAAMI,eAAeL,IAE1BC,EAAMC,SAASI,QAAQN,EAAQb,MAAMiB,SAAWG,IACvCN,EAAMI,eAAeE,KAE1BZ,EAAWa,GAAS,IAAIA,EAAM,WAAW9B,EAAO,OAChDmB,EAAgBW,GAAS,IAAIA,EAAM,gBAAgB9B,EAAO,WAE/D,CAACS,EAAMiB,WAuCVX,OAAAA,EAAAA,UAAU,KACNK,KACD,CAACA,IAGAW,OAAC,UAAQtB,EAAOuB,UAAWC,EAAAA,KAAK,WAAYxB,EAAMuB,WAC7CN,SAAA,CA3Ca,MAClB,MAAMJ,EAAUC,EAAMC,SAASC,QAAQhB,EAAMiB,UAAU,GAEvD,GAAKH,EAAMI,eAA6CL,GAGxD,OAAOC,EAAMW,aAA2CZ,EAAS,CAC7DZ,YAAAA,EACAC,eAAAA,EACAK,OAAAA,EACAE,YAAAA,KAiCCiB,GA5BEZ,EAAMC,SAASY,IAAI3B,EAAMiB,SAAU,CAACW,EAAOC,KAC9C,IACKf,EAAMI,eAELU,IACa,IAAfC,EAEA,OAEJ,MAAMC,EAAgBD,EAAa,EAEnC,OAAOC,IAAkB7B,EACnBa,EAAMW,aAEJG,EAAO,CACL,kBAAmBrB,EAAOuB,GAC1BrC,GAAIgB,EAAYqB,KAEpB","x_google_ignoreList":[0,1]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./useAnimatedHeight/useAnimatedHeight.cjs"),s=require("./useAnimatedHeight/useAnimatedHeightBetween.cjs"),r=require("./useAnimatedHeight/useAutoAnimateHeight.cjs"),u=require("./useBrowserPreferences/useBrowserPreferences.cjs"),i=require("./useIntersectionObserver/useIntersectionObserver.cjs"),t=require("./useLocalStorage/useLocalStorage.cjs"),o=require("./useMutationObserver/useMutationObserver.cjs"),n=require("./usePreviousValue/usePreviousValue.cjs"),c=require("./useProgressiveImg/useProgressiveImg.cjs"),a=require("./useScreen/useScreen.cjs"),g=require("./useScrollIntoView/useScrollIntoView.cjs"),l=require("./useAriaLiveRegion/useAriaLiveRegion.cjs"),d=require("./useClickOutside/useClickOutside.cjs"),m=require("./useFocusOutside/useFocusOutside.cjs"),p=require("./useElementDimensions/useElementDimensions.cjs"),v=require("./useId/useId.cjs"),j=require("./useKeyListener/useKeyListener.cjs"),x=require("./useListNavigation/useListNavigation.cjs"),q=require("./useSwipeGesture/useSwipeGesture.cjs");exports.useAnimatedHeight=e.useAnimatedHeight,exports.useAnimatedHeightBetween=s.useAnimatedHeightBetween,exports.useAutoAnimatedHeight=r.useAutoAnimatedHeight,exports.useBrowserPreferences=u.useBrowserPreferences,exports.useIntersectionObserver=i.useIntersectionObserver,exports.useLocalStorage=t.useLocalStorage,exports.useMutationObserver=o.useMutationObserver,exports.usePreviousValue=n.usePreviousValue,exports.useProgressiveImg=c.useProgressiveImg,exports.useScreen=a.useScreen,exports.useScrollIntoView=g.useScrollIntoView,exports.useAriaLiveRegion=l.useAriaLiveRegion,exports.useClickOutside=d.useClickOutside,exports.useFocusOutside=m.useFocusOutside,exports.useElementDimensions=p.useElementDimensions,exports.useId=v.useId,exports.useKeyListener=j.useKeyListener,exports.useListNavigation=x.useListNavigation,exports.useSwipeGesture=q.useSwipeGesture;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
export { useAnimatedDetails } from './useAnimatedDetails/useAnimatedDetails.cjs';
|
|
2
1
|
export { useAnimatedHeight, useAnimatedHeightBetween, useAutoAnimatedHeight, type UseAutoAnimatedHeightOptions, type UseAnimatedHeightOptions, } from './useAnimatedHeight/index.cjs';
|
|
3
2
|
export { useBrowserPreferences } from './/useBrowserPreferences//useBrowserPreferences.cjs';
|
|
4
3
|
export { useIntersectionObserver } from './useIntersectionObserver/useIntersectionObserver.cjs';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react")
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react"),t=["Control","Alt","Shift","Meta"],r="[role='option'][class~='jkl-select__option'],[class~='jkl-combobox__option'],[class~='jkl-option'],[class~='jkl-search']";function n(e){e&&("BUTTON"===e.nodeName||"INPUT"===e.nodeName?e.focus():e.querySelector("input,button")?.focus())}exports.useListNavigation=function({ref:o,element:c,disableTypeahead:s=!1}){const a=e.useRef(void 0),l=e.useRef(""),u=e.useCallback(e=>{if(s||t.includes(e))return;const u=c??o?.current??null;if(l.current=l.current.concat(e),clearTimeout(a.current),a.current=setTimeout(()=>{l.current="",a.current=void 0},500),!l.current.length)return;const i=u?.querySelectorAll(r);if(i&&i.length)for(const e of i)if(0===e.innerText?.toLowerCase().indexOf(l.current.toLowerCase()))return void n(e)},[c,o,s]),i=e.useCallback(e=>{const t=c??o?.current??null;if(!t)return;const{key:s,target:a}=e,l=a,i=Array.from(t.querySelectorAll(r));switch(s){case"ArrowUp":{e.preventDefault();const t=i.indexOf(l.closest(r));n(i[t-1]);break}case"ArrowDown":{e.preventDefault();const t=i.indexOf(l.closest(r));n(i[t+1]);break}case"PageUp":case"Home":e.preventDefault(),n(i[0]);break;case"PageDown":case"End":e.preventDefault(),n(i[i.length-1]);break;case"Shift":case"Control":case"Alt":case"Meta":case"Enter":case"Escape":case" ":break;case"Tab":e.preventDefault();break;default:u(s)}},[c,o,u]);e.useEffect(()=>{const e=c??o?.current??null;if(e)return e.addEventListener("keydown",i),()=>{e.removeEventListener("keydown",i),clearTimeout(a.current)}},[c,o,i])};
|
|
2
2
|
//# sourceMappingURL=useListNavigation.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useListNavigation.cjs","sources":["../../../../src/hooks/useListNavigation/useListNavigation.ts"],"sourcesContent":["import { type RefObject,
|
|
1
|
+
{"version":3,"file":"useListNavigation.cjs","sources":["../../../../src/hooks/useListNavigation/useListNavigation.ts"],"sourcesContent":["import { type RefObject, useCallback, useEffect, useRef } from \"react\";\n\n/**\n * Enten `ref` eller `element` må gis. `ref` brukes når listen alltid\n * er i DOM-en; `element` foretrekkes når elementet mountes/unmountes\n * dynamisk (f.eks. portalert via floating-ui), slik at listeneren\n * re-festes når elementet faktisk er tilgjengelig.\n */\ntype UseListNavigationProps<T> = {\n disableTypeahead?: boolean;\n} & (\n | {\n ref: RefObject<T | null>;\n element?: never;\n }\n | {\n ref?: never;\n element: T | null;\n }\n);\n\nconst TYPEAHEAD_SEARCH_TIMEOUT = 500;\nconst MODIFIERS = [\"Control\", \"Alt\", \"Shift\", \"Meta\"];\nconst LIST_ITEM_SELECTOR =\n \"[role='option'][class~='jkl-select__option'],[class~='jkl-combobox__option'],[class~='jkl-option'],[class~='jkl-search']\";\n\nexport function useListNavigation<T extends HTMLElement>({\n ref,\n element,\n disableTypeahead = false,\n}: UseListNavigationProps<T>): void {\n const searchResetTimer = useRef<ReturnType<typeof setTimeout> | undefined>(\n undefined,\n );\n const searchTerm = useRef<string>(\"\");\n\n const typeahead = useCallback(\n (key: string): void => {\n if (disableTypeahead || MODIFIERS.includes(key)) return;\n const list = element ?? ref?.current ?? null;\n\n searchTerm.current = searchTerm.current.concat(key);\n clearTimeout(searchResetTimer.current);\n searchResetTimer.current = setTimeout(() => {\n searchTerm.current = \"\";\n searchResetTimer.current = undefined;\n }, TYPEAHEAD_SEARCH_TIMEOUT);\n\n if (!searchTerm.current.length) return;\n\n const listItems =\n list?.querySelectorAll<HTMLElement>(LIST_ITEM_SELECTOR);\n if (!listItems || !listItems.length) return;\n\n for (const item of listItems) {\n if (\n item.innerText\n ?.toLowerCase()\n .indexOf(searchTerm.current.toLowerCase()) === 0\n ) {\n focusButtonOrInput(item);\n return;\n }\n }\n },\n [element, ref, disableTypeahead],\n );\n\n const handleKeyNavigation = useCallback(\n (event: KeyboardEvent): void => {\n const list = element ?? ref?.current ?? null;\n if (!list) return;\n\n const { key, target } = event;\n const current = target as HTMLElement;\n const allItems = Array.from(\n list.querySelectorAll<HTMLElement>(LIST_ITEM_SELECTOR),\n );\n\n switch (key) {\n case \"ArrowUp\": {\n event.preventDefault();\n const index = allItems.indexOf(\n current.closest(LIST_ITEM_SELECTOR) as HTMLElement,\n );\n focusButtonOrInput(allItems[index - 1]);\n break;\n }\n case \"ArrowDown\": {\n event.preventDefault();\n const index = allItems.indexOf(\n current.closest(LIST_ITEM_SELECTOR) as HTMLElement,\n );\n focusButtonOrInput(allItems[index + 1]);\n break;\n }\n case \"PageUp\":\n case \"Home\": {\n event.preventDefault();\n focusButtonOrInput(allItems[0]);\n break;\n }\n case \"PageDown\":\n case \"End\": {\n event.preventDefault();\n focusButtonOrInput(allItems[allItems.length - 1]);\n break;\n }\n // Vi gjør ingenting for modifiers eller mellomrom\n case \"Shift\":\n case \"Control\":\n case \"Alt\":\n case \"Meta\":\n case \"Enter\":\n case \"Escape\":\n case \" \":\n break;\n\n case \"Tab\":\n event.preventDefault();\n break;\n\n // Alle andre taster trigger typeahead\n default:\n typeahead(key);\n break;\n }\n },\n [element, ref, typeahead],\n );\n\n useEffect(() => {\n const list = element ?? ref?.current ?? null;\n if (!list) return;\n\n list.addEventListener(\"keydown\", handleKeyNavigation);\n\n return () => {\n list.removeEventListener(\"keydown\", handleKeyNavigation);\n clearTimeout(searchResetTimer.current);\n };\n }, [element, ref, handleKeyNavigation]);\n}\n\nfunction focusButtonOrInput(element?: Element | null): void {\n if (!element) return;\n\n if (element.nodeName === \"BUTTON\" || element.nodeName === \"INPUT\") {\n (element as HTMLElement).focus();\n } else {\n element\n .querySelector<HTMLInputElement | HTMLButtonElement>(\"input,button\")\n ?.focus();\n }\n}\n"],"names":["MODIFIERS","LIST_ITEM_SELECTOR","focusButtonOrInput","element","nodeName","focus","querySelector","ref","disableTypeahead","searchResetTimer","useRef","searchTerm","typeahead","useCallback","key","includes","list","current","concat","clearTimeout","setTimeout","length","listItems","querySelectorAll","item","innerText","toLowerCase","indexOf","handleKeyNavigation","event","target","allItems","Array","from","preventDefault","index","closest","useEffect","addEventListener","removeEventListener"],"mappings":"yGAsBMA,EAAY,CAAC,UAAW,MAAO,QAAS,QACxCC,EACF,2HAwHJ,SAASC,EAAmBC,GACnBA,IAEoB,WAArBA,EAAQC,UAA8C,UAArBD,EAAQC,SACxCD,EAAwBE,QAEzBF,EACKG,cAAoD,iBACnDD,QAEd,2BAhIO,UACHE,IAAAA,EACAJ,QAAAA,EACAK,iBAAAA,GAAmB,IAEnB,MAAMC,EAAmBC,EAAAA,YACrB,GAEEC,EAAaD,EAAAA,OAAe,IAE5BE,EAAYC,EAAAA,YACbC,IACG,GAAIN,GAAoBR,EAAUe,SAASD,GAAM,OACjD,MAAME,EAAOb,GAAWI,GAAKU,SAAW,KASxC,GAPAN,EAAWM,QAAUN,EAAWM,QAAQC,OAAOJ,GAC/CK,aAAaV,EAAiBQ,SAC9BR,EAAiBQ,QAAUG,WAAW,KAClCT,EAAWM,QAAU,GACrBR,EAAiBQ,aAAU,GAxBV,MA2BhBN,EAAWM,QAAQI,OAAQ,OAEhC,MAAMC,EACFN,GAAMO,iBAA8BtB,GACxC,GAAKqB,GAAcA,EAAUD,OAE7B,IAAA,MAAWG,KAAQF,EACf,GAGuD,IAFnDE,EAAKC,WACCC,cACDC,QAAQhB,EAAWM,QAAQS,eAGhC,YADAxB,EAAmBsB,IAK/B,CAACrB,EAASI,EAAKC,IAGboB,EAAsBf,EAAAA,YACvBgB,IACG,MAAMb,EAAOb,GAAWI,GAAKU,SAAW,KACxC,IAAKD,EAAM,OAEX,MAAQF,IAAAA,EAAKgB,OAAAA,GAAWD,EAClBZ,EAAUa,EACVC,EAAWC,MAAMC,KACnBjB,EAAKO,iBAA8BtB,IAGvC,OAAQa,GACJ,IAAK,UAAW,CACZe,EAAMK,iBACN,MAAMC,EAAQJ,EAASJ,QACnBV,EAAQmB,QAAQnC,IAEpBC,EAAmB6B,EAASI,EAAQ,IACpC,KACJ,CACA,IAAK,YAAa,CACdN,EAAMK,iBACN,MAAMC,EAAQJ,EAASJ,QACnBV,EAAQmB,QAAQnC,IAEpBC,EAAmB6B,EAASI,EAAQ,IACpC,KACJ,CACA,IAAK,SACL,IAAK,OACDN,EAAMK,iBACNhC,EAAmB6B,EAAS,IAC5B,MAEJ,IAAK,WACL,IAAK,MACDF,EAAMK,iBACNhC,EAAmB6B,EAASA,EAASV,OAAS,IAC9C,MAGJ,IAAK,QACL,IAAK,UACL,IAAK,MACL,IAAK,OACL,IAAK,QACL,IAAK,SACL,IAAK,IACD,MAEJ,IAAK,MACDQ,EAAMK,iBACN,MAGJ,QACItB,EAAUE,KAItB,CAACX,EAASI,EAAKK,IAGnByB,EAAAA,UAAU,KACN,MAAMrB,EAAOb,GAAWI,GAAKU,SAAW,KACxC,GAAKD,EAEL,OAAAA,EAAKsB,iBAAiB,UAAWV,GAE1B,KACHZ,EAAKuB,oBAAoB,UAAWX,GACpCT,aAAaV,EAAiBQ,WAEnC,CAACd,EAASI,EAAKqB,GACtB"}
|