@verbb/plugin-kit-web 2.0.9 → 2.0.11
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/CHANGELOG.md +17 -0
- package/dist/chunks/{animate-with-class-CsDwYnXL.js → animate-with-class-ZJeCOKB3.js} +1 -1
- package/dist/chunks/{animate-with-class-CsDwYnXL.js.map → animate-with-class-ZJeCOKB3.js.map} +1 -1
- package/dist/chunks/{autoloader-hkX3zcAt.js → autoloader-DPX9YYZs.js} +2 -2
- package/dist/chunks/{autoloader-hkX3zcAt.js.map → autoloader-DPX9YYZs.js.map} +1 -1
- package/dist/chunks/{component-registry-BOlxFlou.js → component-registry-CNB8PbP_.js} +5 -1
- package/dist/chunks/component-registry-CNB8PbP_.js.map +1 -0
- package/dist/chunks/{pk-calendar-TEFA09cI.js → pk-calendar-CoUil0F7.js} +1 -1
- package/dist/chunks/{pk-calendar-TEFA09cI.js.map → pk-calendar-CoUil0F7.js.map} +1 -1
- package/dist/chunks/{pk-color-input-CNnmHJJB.js → pk-color-input-BCCXCZMA.js} +1 -1
- package/dist/chunks/{pk-color-input-CNnmHJJB.js.map → pk-color-input-BCCXCZMA.js.map} +1 -1
- package/dist/chunks/pk-connect.styles-DshgIW2n.js +68 -0
- package/dist/chunks/pk-connect.styles-DshgIW2n.js.map +1 -0
- package/dist/chunks/{pk-copy-button-C17MLLYS.js → pk-copy-button-CfeVuQ0r.js} +1 -1
- package/dist/chunks/{pk-copy-button-C17MLLYS.js.map → pk-copy-button-CfeVuQ0r.js.map} +1 -1
- package/dist/chunks/{pk-date-picker-x-qkpQWF.js → pk-date-picker-BM4HMb4-.js} +2 -2
- package/dist/chunks/{pk-date-picker-x-qkpQWF.js.map → pk-date-picker-BM4HMb4-.js.map} +1 -1
- package/dist/chunks/{pk-dialog-BXJr3iEo.js → pk-dialog-Ck1InIBC.js} +3 -2
- package/dist/chunks/{pk-dialog-BXJr3iEo.js.map → pk-dialog-Ck1InIBC.js.map} +1 -1
- package/dist/chunks/{pk-dropdown-item-P3LLojCI.js → pk-dropdown-item-HcIUlFH1.js} +1 -1
- package/dist/chunks/{pk-dropdown-item-P3LLojCI.js.map → pk-dropdown-item-HcIUlFH1.js.map} +1 -1
- package/dist/chunks/{pk-dropdown-label-ibVrU6-U.js → pk-dropdown-label-DLgrmYND.js} +1 -1
- package/dist/chunks/{pk-dropdown-label-ibVrU6-U.js.map → pk-dropdown-label-DLgrmYND.js.map} +1 -1
- package/dist/chunks/{pk-dropdown-menu-CsX95MCP.js → pk-dropdown-menu-r5wgkvmZ.js} +3 -3
- package/dist/chunks/{pk-dropdown-menu-CsX95MCP.js.map → pk-dropdown-menu-r5wgkvmZ.js.map} +1 -1
- package/dist/chunks/{pk-editable-table-fPL8Zbbg.js → pk-editable-table-DQZQ6JLb.js} +8 -8
- package/dist/chunks/{pk-editable-table-fPL8Zbbg.js.map → pk-editable-table-DQZQ6JLb.js.map} +1 -1
- package/dist/chunks/{pk-field-Buy_AtYF.js → pk-field-JFP24j4o.js} +2 -2
- package/dist/chunks/{pk-field-Buy_AtYF.js.map → pk-field-JFP24j4o.js.map} +1 -1
- package/dist/chunks/{pk-option-C-cR-jOv.js → pk-option-Cy7oOcwF.js} +1 -1
- package/dist/chunks/{pk-option-C-cR-jOv.js.map → pk-option-Cy7oOcwF.js.map} +1 -1
- package/dist/chunks/{pk-option-group-CbI56A3T.js → pk-option-group-BAFSIZTa.js} +1 -1
- package/dist/chunks/{pk-option-group-CbI56A3T.js.map → pk-option-group-BAFSIZTa.js.map} +1 -1
- package/dist/chunks/{pk-popover-CVvwXMld.js → pk-popover-G3ojheBD.js} +1 -1
- package/dist/chunks/{pk-popover-CVvwXMld.js.map → pk-popover-G3ojheBD.js.map} +1 -1
- package/dist/chunks/{pk-radio-Bg02ckzC.js → pk-radio-CDfhOW8L.js} +1 -1
- package/dist/chunks/{pk-radio-Bg02ckzC.js.map → pk-radio-CDfhOW8L.js.map} +1 -1
- package/dist/chunks/{pk-radio-group-B5rps9G4.js → pk-radio-group-BazmLDvl.js} +1 -1
- package/dist/chunks/{pk-radio-group-B5rps9G4.js.map → pk-radio-group-BazmLDvl.js.map} +1 -1
- package/dist/chunks/{pk-scroll-area-B0V4Dr2j.js → pk-scroll-area-BjU7-vZX.js} +1 -1
- package/dist/chunks/{pk-scroll-area-B0V4Dr2j.js.map → pk-scroll-area-BjU7-vZX.js.map} +1 -1
- package/dist/chunks/{pk-select-BPnO9qgj.js → pk-select-BeMDXEC6.js} +1 -1
- package/dist/chunks/{pk-select-BPnO9qgj.js.map → pk-select-BeMDXEC6.js.map} +1 -1
- package/dist/chunks/{pk-tab-BdoPiYfT.js → pk-tab-f1OLMVXs.js} +1 -1
- package/dist/chunks/{pk-tab-BdoPiYfT.js.map → pk-tab-f1OLMVXs.js.map} +1 -1
- package/dist/chunks/{pk-tab-heading-BWAB85ua.js → pk-tab-heading-79ZuLhXi.js} +1 -1
- package/dist/chunks/{pk-tab-heading-BWAB85ua.js.map → pk-tab-heading-79ZuLhXi.js.map} +1 -1
- package/dist/chunks/{pk-tab-panel-Q3Pqyq-f.js → pk-tab-panel-DdAbrOBF.js} +1 -1
- package/dist/chunks/{pk-tab-panel-Q3Pqyq-f.js.map → pk-tab-panel-DdAbrOBF.js.map} +1 -1
- package/dist/chunks/{pk-tabs-Cip4nbb7.js → pk-tabs-BhC5PAnO.js} +1 -1
- package/dist/chunks/{pk-tabs-Cip4nbb7.js.map → pk-tabs-BhC5PAnO.js.map} +1 -1
- package/dist/chunks/{pk-time-picker-CZGr2dI2.js → pk-time-picker-RlAqlho4.js} +3 -3
- package/dist/chunks/{pk-time-picker-CZGr2dI2.js.map → pk-time-picker-RlAqlho4.js.map} +1 -1
- package/dist/chunks/{pk-tiptap-content-DAtNbJYC.js → pk-tiptap-content-zzx3-xrD.js} +2 -2
- package/dist/chunks/{pk-tiptap-content-DAtNbJYC.js.map → pk-tiptap-content-zzx3-xrD.js.map} +1 -1
- package/dist/chunks/{pk-tiptap-editor-HemVPILE.js → pk-tiptap-editor-DpT4TYdi.js} +7 -7
- package/dist/chunks/{pk-tiptap-editor-HemVPILE.js.map → pk-tiptap-editor-DpT4TYdi.js.map} +1 -1
- package/dist/chunks/{pk-tiptap-input-CXcYXbRa.js → pk-tiptap-input-D7xj13FY.js} +2 -2
- package/dist/chunks/{pk-tiptap-input-CXcYXbRa.js.map → pk-tiptap-input-D7xj13FY.js.map} +1 -1
- package/dist/chunks/{pk-tooltip-fcUbVGli.js → pk-tooltip-DAq-JZpg.js} +1 -1
- package/dist/chunks/{pk-tooltip-fcUbVGli.js.map → pk-tooltip-DAq-JZpg.js.map} +1 -1
- package/dist/chunks/{register-bvWnvR5a.js → register-C9xZttKy.js} +33 -28
- package/dist/chunks/register-C9xZttKy.js.map +1 -0
- package/dist/chunks/{register-components-BG_6_v_T.js → register-components-B-qCPFFh.js} +1 -1
- package/dist/chunks/{register-components-BG_6_v_T.js.map → register-components-B-qCPFFh.js.map} +1 -1
- package/dist/chunks/{tiptap.styles-BytOpP0H.js → tiptap.styles-ChAfyVi9.js} +1 -1
- package/dist/chunks/{tiptap.styles-BytOpP0H.js.map → tiptap.styles-ChAfyVi9.js.map} +1 -1
- package/dist/component-registry.d.ts.map +1 -1
- package/dist/components/calendar/pk-calendar.js +1 -1
- package/dist/components/calendar.js +1 -1
- package/dist/components/color-input/pk-color-input.js +1 -1
- package/dist/components/color-input.js +1 -1
- package/dist/components/connect/index.d.ts +3 -0
- package/dist/components/connect/index.d.ts.map +1 -0
- package/dist/components/connect/pk-connect-oauth.d.ts +42 -0
- package/dist/components/connect/pk-connect-oauth.d.ts.map +1 -0
- package/dist/components/connect/pk-connect-oauth.js +136 -0
- package/dist/components/connect/pk-connect-oauth.js.map +1 -0
- package/dist/components/connect/pk-connect.d.ts +58 -0
- package/dist/components/connect/pk-connect.d.ts.map +1 -0
- package/dist/components/connect/pk-connect.js +260 -0
- package/dist/components/connect/pk-connect.js.map +1 -0
- package/dist/components/connect/pk-connect.styles.d.ts +8 -0
- package/dist/components/connect/pk-connect.styles.d.ts.map +1 -0
- package/dist/components/connect.d.ts +2 -0
- package/dist/components/connect.js +3 -0
- package/dist/components/copy-button/pk-copy-button.js +1 -1
- package/dist/components/copy-button.js +1 -1
- package/dist/components/date-picker/pk-date-picker.js +1 -1
- package/dist/components/date-picker.js +1 -1
- package/dist/components/dialog/pk-dialog.d.ts.map +1 -1
- package/dist/components/dialog/pk-dialog.js +1 -1
- package/dist/components/dialog.js +1 -1
- package/dist/components/dropdown-menu/pk-dropdown-item.js +1 -1
- package/dist/components/dropdown-menu/pk-dropdown-label.js +1 -1
- package/dist/components/dropdown-menu/pk-dropdown-menu.js +1 -1
- package/dist/components/dropdown-menu.js +3 -3
- package/dist/components/editable-table/pk-editable-table.js +1 -1
- package/dist/components/editable-table.js +1 -1
- package/dist/components/field/pk-field.js +1 -1
- package/dist/components/field.js +1 -1
- package/dist/components/popover/pk-popover.js +1 -1
- package/dist/components/popover.js +1 -1
- package/dist/components/radio-group/pk-radio-group.js +1 -1
- package/dist/components/radio-group/pk-radio.js +1 -1
- package/dist/components/radio-group.js +2 -2
- package/dist/components/scroll-area/pk-scroll-area.js +1 -1
- package/dist/components/scroll-area.js +1 -1
- package/dist/components/select/pk-option-group.js +1 -1
- package/dist/components/select/pk-option.js +1 -1
- package/dist/components/select/pk-select.js +1 -1
- package/dist/components/select.js +3 -3
- package/dist/components/tabs/pk-tab-heading.js +1 -1
- package/dist/components/tabs/pk-tab-panel.js +1 -1
- package/dist/components/tabs/pk-tab.js +1 -1
- package/dist/components/tabs/pk-tabs.js +1 -1
- package/dist/components/tabs.js +4 -4
- package/dist/components/time-picker/pk-time-picker.js +1 -1
- package/dist/components/time-picker.js +1 -1
- package/dist/components/tiptap/pk-tiptap-content.js +1 -1
- package/dist/components/tiptap/pk-tiptap-editor.js +1 -1
- package/dist/components/tiptap/pk-tiptap-input.js +1 -1
- package/dist/components/tiptap-content.js +1 -1
- package/dist/components/tiptap-editor.js +1 -1
- package/dist/components/tiptap-input.js +1 -1
- package/dist/components/tooltip/pk-tooltip.js +1 -1
- package/dist/components/tooltip.js +1 -1
- package/dist/connect/register-cp-connect.d.ts +3 -0
- package/dist/connect/register-cp-connect.d.ts.map +1 -0
- package/dist/connect/register-cp-connect.js +40 -0
- package/dist/connect/register-cp-connect.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +37 -32
- package/dist/index.js.map +1 -1
- package/dist/internal/safe-custom-element.d.ts +20 -0
- package/dist/internal/safe-custom-element.d.ts.map +1 -0
- package/dist/plugin-kit.css +2 -0
- package/dist/plugin-kit.js +2 -2
- package/dist/register-components.js +1 -1
- package/dist/register-pk.generated.d.ts +4 -0
- package/dist/register-pk.generated.d.ts.map +1 -1
- package/dist/register.d.ts +4 -1
- package/dist/register.d.ts.map +1 -1
- package/dist/register.js +34 -31
- package/dist/styles/connect/pk-connect.css +231 -0
- package/dist/utilities/fouce.css +2 -0
- package/dist-loader/chunks/{button-group-item.styles-BNc-ksl1.js → button-group-item.styles-CsBQ3Cyh.js} +1 -1
- package/dist-loader/chunks/{lit-Dnn7gEi2.js → lit-DpLik9Rf.js} +14 -16
- package/dist-loader/chunks/{pk-base-BlxAYXJD.js → pk-base-B21zXxSo.js} +1 -1
- package/dist-loader/chunks/{pk-button-Qg2Tot_-.js → pk-button-Dh4gjLHw.js} +5 -5
- package/dist-loader/chunks/{pk-calendar-CtlUN6iw.js → pk-calendar-n1bwSO7X.js} +5 -5
- package/dist-loader/chunks/{pk-checkbox-CoDX2G3J.js → pk-checkbox-BrZQB816.js} +5 -5
- package/dist-loader/chunks/{pk-color-input-B73zaGYj.js → pk-color-input-sS05YOwT.js} +5 -5
- package/dist-loader/chunks/{pk-combobox-BpGW0asd.js → pk-combobox-B7q6alzE.js} +13 -13
- package/dist-loader/chunks/pk-connect.styles-BAgeFns_.js +273 -0
- package/dist-loader/chunks/{pk-date-picker-DPg627Ad.js → pk-date-picker-Dni5ty79.js} +14 -14
- package/dist-loader/chunks/{pk-dialog-DPn2BXOq.js → pk-dialog-BpPRqFMm.js} +7 -6
- package/dist-loader/chunks/{pk-dropdown-item-CdBLgJoh.js → pk-dropdown-item-CHkFNlA9.js} +7 -7
- package/dist-loader/chunks/{pk-dropdown-menu-BX4lGvGe.js → pk-dropdown-menu-BHVOMNV1.js} +9 -9
- package/dist-loader/chunks/{pk-field-CmPZQ86w.js → pk-field-CJ09ll1S.js} +5 -5
- package/dist-loader/chunks/pk-icon-B-OBmJ3K.js +47 -0
- package/dist-loader/chunks/{pk-input-88DVgoVz.js → pk-input-CEw3AdYt.js} +9 -9
- package/dist-loader/chunks/{pk-lightswitch-BHEOy7aK.js → pk-lightswitch-DJEUScgo.js} +7 -7
- package/dist-loader/chunks/{pk-option-DL4rxbo2.js → pk-option-CunPIei0.js} +4 -4
- package/dist-loader/chunks/{pk-popup-BYFbKaHH.js → pk-popup-FDdBxb4k.js} +5 -5
- package/dist-loader/chunks/{pk-select-D0Ia0Mz3.js → pk-select-CbAaQ7uE.js} +13 -13
- package/dist-loader/chunks/{pk-spinner-Di9O69-m.js → pk-spinner-CIbXjDnp.js} +3 -3
- package/dist-loader/chunks/pk-status-BRIVW7EH.js +89 -0
- package/dist-loader/chunks/{pk-textarea-LC_CPUav.js → pk-textarea-C_rOUtFS.js} +7 -7
- package/dist-loader/chunks/{pk-time-picker-CesVpPiv.js → pk-time-picker-Dr3uvbvc.js} +6 -6
- package/dist-loader/chunks/{pk-tooltip-DRU95AZ6.js → pk-tooltip-HwZ0zRd2.js} +6 -6
- package/dist-loader/chunks/{popup-content-animation.styles-C9ffC35f.js → popup-content-animation.styles-duCg9-CH.js} +1 -1
- package/dist-loader/chunks/{tiptap-_LAjdgeV.js → tiptap-Db7MTUH1.js} +1 -1
- package/dist-loader/chunks/{tiptap.styles-gpE_nQ_B.js → tiptap.styles-BIRIMP7I.js} +2 -2
- package/dist-loader/components/button/button.js +1 -1
- package/dist-loader/components/button-group/button-group-separator.js +3 -3
- package/dist-loader/components/button-group/button-group-text.js +4 -4
- package/dist-loader/components/button-group/button-group.js +3 -3
- package/dist-loader/components/calendar/calendar.js +1 -1
- package/dist-loader/components/checkbox/checkbox.js +1 -1
- package/dist-loader/components/checkbox-select/checkbox-select.js +4 -4
- package/dist-loader/components/code-editor/code-editor.js +5 -5
- package/dist-loader/components/color-input/color-input.js +1 -1
- package/dist-loader/components/combobox/combobox.js +1 -1
- package/dist-loader/components/connect/connect-oauth.js +132 -0
- package/dist-loader/components/connect/connect.js +256 -0
- package/dist-loader/components/copy-button/copy-button.js +5 -5
- package/dist-loader/components/date-picker/date-picker.js +1 -1
- package/dist-loader/components/dialog/dialog.js +1 -1
- package/dist-loader/components/dropdown-menu/dropdown-item.js +1 -1
- package/dist-loader/components/dropdown-menu/dropdown-label.js +3 -3
- package/dist-loader/components/dropdown-menu/dropdown-menu.js +1 -1
- package/dist-loader/components/dropdown-menu/dropdown-separator.js +3 -3
- package/dist-loader/components/editable-table/editable-table.js +18 -18
- package/dist-loader/components/field/field.js +1 -1
- package/dist-loader/components/icon/icon.js +3 -47
- package/dist-loader/components/input/input.js +1 -1
- package/dist-loader/components/input-group/input-group-addon.js +3 -3
- package/dist-loader/components/input-group/input-group-button.js +3 -3
- package/dist-loader/components/input-group/input-group-input.js +3 -3
- package/dist-loader/components/input-group/input-group-text.js +3 -3
- package/dist-loader/components/input-group/input-group-textarea.js +3 -3
- package/dist-loader/components/input-group/input-group.js +4 -4
- package/dist-loader/components/lightswitch/lightswitch.js +1 -1
- package/dist-loader/components/popover/popover.js +9 -9
- package/dist-loader/components/popup/popup.js +1 -1
- package/dist-loader/components/radio-group/radio-group.js +6 -6
- package/dist-loader/components/radio-group/radio.js +3 -3
- package/dist-loader/components/scroll-area/scroll-area.js +3 -3
- package/dist-loader/components/select/option-group.js +3 -3
- package/dist-loader/components/select/option.js +1 -1
- package/dist-loader/components/select/select.js +1 -1
- package/dist-loader/components/separator/separator.js +3 -3
- package/dist-loader/components/spinner/spinner.js +1 -1
- package/dist-loader/components/status/status.js +1 -88
- package/dist-loader/components/tabs/tab-heading.js +3 -3
- package/dist-loader/components/tabs/tab-panel.js +3 -3
- package/dist-loader/components/tabs/tab.js +3 -3
- package/dist-loader/components/tabs/tabs.js +3 -3
- package/dist-loader/components/textarea/textarea.js +1 -1
- package/dist-loader/components/time-picker/time-picker.js +1 -1
- package/dist-loader/components/tiptap/tiptap-content.js +5 -5
- package/dist-loader/components/tiptap/tiptap-editor.js +15 -15
- package/dist-loader/components/tiptap/tiptap-input.js +6 -6
- package/dist-loader/components/toggle/toggle.js +4 -4
- package/dist-loader/components/toggle-group/toggle-group.js +3 -3
- package/dist-loader/components/tooltip/tooltip.js +1 -1
- package/dist-loader/plugin-kit.css +2 -0
- package/dist-loader/plugin-kit.loader.js +4 -0
- package/dist-loader/styles/connect/pk-connect.css +231 -0
- package/dist-loader/utilities/fouce.css +2 -0
- package/package.json +52 -7
- package/dist/chunks/component-registry-BOlxFlou.js.map +0 -1
- package/dist/chunks/register-bvWnvR5a.js.map +0 -1
- /package/dist-loader/chunks/{animate-with-class-B2hHgK5M.js → animate-with-class-DT0jwaR_.js} +0 -0
- /package/dist-loader/chunks/{codemirror-CHXb-wYU.js → codemirror-CSgOT0QM.js} +0 -0
- /package/dist-loader/chunks/{field-labels-Vo3wHq49.js → field-labels-D3lKQ2nq.js} +0 -0
- /package/dist-loader/chunks/{floating-ui-BTBNFWAR.js → floating-ui-DU6GNott.js} +0 -0
- /package/dist-loader/chunks/{has-slot-BZDcCpf9.js → has-slot-BGJeJdHr.js} +0 -0
- /package/dist-loader/chunks/{mirror-validator-DEz3BsbN.js → mirror-validator-C5XrXPaq.js} +0 -0
- /package/dist-loader/chunks/{overlay-lifecycle-BG4QMRLw.js → overlay-lifecycle-C3tSQ3UR.js} +0 -0
- /package/dist-loader/chunks/{pk-clear-BRS8vkV-.js → pk-clear-BMZUzwDt.js} +0 -0
- /package/dist-loader/chunks/{popup-placement-animation-BPjq650B.js → popup-placement-animation-WlEXnS85.js} +0 -0
- /package/dist-loader/chunks/{popup-pointer-BTS3Y6LE.js → popup-pointer-caPc8kwB.js} +0 -0
- /package/dist-loader/chunks/{render-B_9MG170.js → render-Niz5wYRa.js} +0 -0
- /package/dist-loader/chunks/{required-validator-DXqqPVeW.js → required-validator-0XwZtX9k.js} +0 -0
- /package/dist-loader/chunks/{sync-listbox-separators-CT3oGzTf.js → sync-listbox-separators-Dk_E_IVa.js} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pk-field-Buy_AtYF.js","names":[],"sources":["../../src/base/markdown.styles.ts","../../src/internal/field-aria.ts","../../src/utils/inline-markdown.ts","../../src/components/field/pk-field.styles.ts","../../src/components/field/pk-field.ts"],"sourcesContent":["import { css } from 'lit';\n\n/** Shared inline markdown styling for field instructions, errors, and warnings. */\nexport const inlineMarkdownStyles = css`\n @layer pk-component {\n .pk-inline-markdown a {\n color: var(--pk-color-blue-500);\n text-decoration: none;\n }\n\n .pk-inline-markdown a:hover {\n text-decoration: underline;\n }\n\n /* Craft p code — gray chip; tip/warning/error override bg/border on pk-field. */\n .pk-inline-markdown code {\n /* Craft --border-hairline ≈ gray-800 @ 10%. */\n border: 1px solid color-mix(in srgb, var(--pk-color-gray-800) 10%, transparent);\n border-radius: var(--pk-radius-sm);\n background: var(--pk-color-gray-100);\n padding-block: 0.0625em;\n padding-inline: 0.25em;\n font-family: var(--pk-font-family-mono, ui-monospace, monospace);\n /* v1 field help/errors used [&_code]:text-[0.85em] — tighter than --pk-font-size-mono (0.9em). */\n font-size: var(--pk-inline-markdown-code-font-size, 0.85em);\n line-height: var(--pk-line-height-mono, 1.5);\n /* Inherit tip/warning/error/instructions text color (Craft parity). */\n color: inherit;\n }\n }\n`;\n","export type SyncFieldAriaOptions = {\n control: HTMLElement;\n labelId: string;\n instructionsId: string;\n errorsId: string;\n warningId: string;\n tipId: string;\n controlId: string;\n hasLabel: boolean;\n hasInstructions: boolean;\n hasErrors: boolean;\n hasWarning: boolean;\n hasTip: boolean;\n hasRequired?: boolean;\n invalid?: boolean;\n};\n\n/** Wires label/instructions/errors/warning/tip ids to a slotted field control. */\nexport function syncFieldAria({\n control,\n labelId,\n instructionsId,\n errorsId,\n warningId,\n tipId,\n controlId,\n hasLabel,\n hasInstructions,\n hasErrors,\n hasWarning,\n hasTip,\n hasRequired = false,\n invalid = false,\n}: SyncFieldAriaOptions): void {\n if (!control.id) {\n control.id = controlId;\n }\n\n if (hasLabel) {\n control.setAttribute('aria-labelledby', labelId);\n } else {\n control.removeAttribute('aria-labelledby');\n }\n\n const describedBy = [\n hasInstructions ? instructionsId : '',\n hasErrors ? errorsId : '',\n hasWarning ? warningId : '',\n hasTip ? tipId : '',\n ].filter(Boolean);\n\n if (describedBy.length > 0) {\n control.setAttribute('aria-describedby', describedBy.join(' '));\n } else {\n control.removeAttribute('aria-describedby');\n }\n\n if (hasRequired) {\n control.setAttribute('aria-required', 'true');\n } else {\n control.removeAttribute('aria-required');\n }\n\n // Kit controls (pk-input, etc.) paint error chrome from reflected `invalid`.\n // v1 Input used Tailwind `aria-invalid:border-*` — aria alone is not enough now.\n const isInvalid = Boolean(invalid || hasErrors);\n\n if (isInvalid) {\n control.setAttribute('aria-invalid', 'true');\n control.setAttribute('aria-errormessage', errorsId);\n } else {\n control.removeAttribute('aria-invalid');\n control.removeAttribute('aria-errormessage');\n }\n\n syncControlInvalidState(control, isInvalid);\n}\n\n/** Prefer the Lit `invalid` property when present; otherwise toggle the attribute. */\nfunction syncControlInvalidState(control: HTMLElement, isInvalid: boolean): void {\n if ('invalid' in control) {\n (control as HTMLElement & { invalid: boolean }).invalid = isInvalid;\n return;\n }\n\n control.toggleAttribute('invalid', isInvalid);\n}\n","import { renderInlineMarkdown } from '@verbb/plugin-kit-core';\nimport { nothing } from 'lit';\nimport { unsafeHTML, type UnsafeHTMLDirective } from 'lit/directives/unsafe-html.js';\nimport type { DirectiveResult } from 'lit/directive.js';\n\n/** Renders inline markdown for Lit templates (bold, italic, links, code). */\nexport function inlineMarkdown(content: string): DirectiveResult<typeof UnsafeHTMLDirective> | typeof nothing {\n if (!content) {\n return nothing;\n }\n\n const html = renderInlineMarkdown(content);\n\n if (!html) {\n return nothing;\n }\n\n return unsafeHTML(html);\n}\n","import { css } from 'lit';\n\nexport const pkFieldStyles = css`\n @layer pk-component {\n :host {\n display: block;\n width: 100%;\n }\n\n .form-control__control {\n display: block;\n position: relative;\n width: 100%;\n }\n\n .form-control__header--with-end {\n flex-direction: row;\n align-items: flex-start;\n justify-content: space-between;\n gap: 0.75rem;\n }\n\n .form-control__header-main {\n display: flex;\n flex-direction: column;\n gap: 0.125rem;\n min-width: 0;\n flex: 1 1 auto;\n }\n\n .form-control__header-end {\n flex-shrink: 0;\n }\n\n .form-control__required {\n display: inline-flex;\n align-items: center;\n color: var(--pk-color-rose-600);\n line-height: 0;\n }\n\n .form-control__required svg {\n display: block;\n width: 10px;\n height: 10px;\n }\n\n .form-control__translatable {\n display: inline-flex;\n align-items: center;\n color: var(--pk-color-gray-550);\n line-height: 0;\n }\n\n .form-control__translatable svg {\n display: block;\n width: 1rem;\n height: 1rem;\n fill: currentColor;\n }\n\n .form-control__errors {\n margin: 0;\n padding-inline-start: 20px;\n color: var(--pk-color-error);\n font-family: var(--pk-font-family);\n font-size: var(--pk-font-size-base);\n line-height: var(--pk-line-height);\n list-style: square;\n }\n\n .form-control__errors:empty {\n display: none;\n }\n\n .form-control__warning {\n display: flex;\n align-items: flex-start;\n gap: 0.25rem;\n min-width: 0;\n margin: 0;\n color: var(--pk-color-warning);\n font-family: var(--pk-font-family);\n font-size: var(--pk-font-size-base);\n line-height: var(--pk-line-height);\n }\n\n .form-control__warning:empty {\n display: none;\n }\n\n .form-control__warning-icon {\n display: inline-flex;\n flex-shrink: 0;\n margin-top: 0.3em;\n width: 0.75rem;\n height: 0.75rem;\n line-height: 0;\n }\n\n .form-control__warning-text {\n min-width: 0;\n margin: 0;\n }\n\n .form-control__warning-icon svg {\n display: block;\n width: 100%;\n height: 100%;\n }\n\n /* Craft .warning code — amber chip matching warning text. */\n .form-control__warning .pk-inline-markdown code {\n background-color: var(--pk-color-amber-100);\n border-color: var(--pk-color-amber-300);\n }\n\n .form-control__tip {\n display: flex;\n align-items: flex-start;\n gap: 0.25rem;\n min-width: 0;\n margin: 0;\n color: var(--pk-color-sky-700);\n font-family: var(--pk-font-family);\n font-size: var(--pk-font-size-base);\n line-height: var(--pk-line-height);\n }\n\n .form-control__tip:empty {\n display: none;\n }\n\n .form-control__tip-icon {\n display: inline-flex;\n flex-shrink: 0;\n margin-top: 0.3em;\n width: 0.75rem;\n height: 0.75rem;\n line-height: 0;\n }\n\n .form-control__tip-text {\n min-width: 0;\n margin: 0;\n }\n\n .form-control__tip-icon svg {\n display: block;\n width: 100%;\n height: 100%;\n }\n\n .form-control__tip-text a {\n text-decoration: underline;\n }\n\n /* Craft .tip code — sky/notice chip matching tip text. */\n .form-control__tip .pk-inline-markdown code {\n background-color: var(--pk-color-sky-100);\n border-color: var(--pk-color-sky-300);\n }\n\n /* Craft --bg-error / --border-error pattern for field errors. */\n .form-control__errors.pk-inline-markdown code {\n background-color: var(--pk-color-red-100);\n border-color: var(--pk-color-red-300);\n }\n }\n`;\n","import { html, nothing } from 'lit';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { customElement, property, query } from 'lit/decorators.js';\nimport type { PropertyValues } from 'lit';\n\nimport { uniqueId } from '../../a11y/focus.js';\nimport { formControlStyles } from '../../base/form-control.styles.js';\nimport { inlineMarkdownStyles } from '../../base/markdown.styles.js';\nimport { PkElement } from '../../base/pk-element.js';\nimport { createIconElement, createTranslationIconElement, asterisk, lightbulb, triangleExclamation } from '../../icons/index.js';\nimport { syncFieldAria } from '../../internal/field-aria.js';\nimport { HasSlotController } from '../../internal/has-slot.js';\nimport { inlineMarkdown } from '../../utils/inline-markdown.js';\nimport { pkFieldStyles } from './pk-field.styles.js';\n\n/**\n * Form field shell — label, instructions, errors, warning, and tip around a slotted control.\n *\n * Mirrors Plugin Kit React `FieldLayout`. Use for schema-driven forms; controls may\n * also expose their own `label` / `instructions` for standalone usage.\n *\n * @slot label - Field label\n * @slot instructions - Help text below the label (property values support inline Markdown)\n * @slot hint - Alias for `instructions`\n * @slot header-end - Extra header actions (React `headerEnd`)\n * @slot errors - Custom error content (property values support inline Markdown)\n * @slot warning - Warning message (property values support inline Markdown)\n * @slot tip - Informational tip below the control (property values support inline Markdown)\n * @slot - Field control (`pk-input`, `pk-select`, etc.)\n *\n * @csspart header - Field header row\n * @csspart header-end - Trailing header actions\n * @csspart form-control - Root wrapper\n * @csspart label - Label element\n * @csspart control - Control slot wrapper\n * @csspart instructions - Instructions region\n * @csspart errors - Errors list\n * @csspart warning - Warning region\n * @csspart tip - Tip region\n */\n@customElement('pk-field')\nexport class PkField extends PkElement {\n static override styles = [formControlStyles, inlineMarkdownStyles, pkFieldStyles];\n\n private readonly hasSlotController = new HasSlotController(\n this,\n 'label',\n 'instructions',\n 'hint',\n 'header-end',\n 'warning',\n 'tip',\n 'errors',\n );\n\n private readonly baseId = uniqueId('pk-field');\n\n @property()\n label = '';\n\n @property()\n instructions = '';\n\n @property({ type: Boolean, reflect: true })\n required = false;\n\n /** Shows the translatable-field icon beside the label. */\n @property({ type: Boolean, reflect: true })\n translatable = false;\n\n @property()\n warning = '';\n\n @property()\n tip = '';\n\n @property({ attribute: false })\n errors: string[] = [];\n\n /** Associates the label with a control id in the light DOM. */\n @property({ reflect: true })\n for = '';\n\n @query('slot:not([name])')\n private controlSlot!: HTMLSlotElement;\n\n override connectedCallback(): void {\n super.connectedCallback();\n\n const legacyHint = this.getAttribute('hint');\n\n if (legacyHint && !this.instructions) {\n this.instructions = legacyHint;\n }\n }\n\n override updated(changed: PropertyValues): void {\n super.updated(changed);\n\n if (\n changed.has('label')\n || changed.has('instructions')\n || changed.has('errors')\n || changed.has('warning')\n || changed.has('tip')\n || changed.has('required')\n || changed.has('for')\n ) {\n this.syncControlAria();\n }\n }\n\n private get labelId(): string {\n return `${this.baseId}-label`;\n }\n\n private get instructionsId(): string {\n return `${this.baseId}-instructions`;\n }\n\n private get errorsId(): string {\n return `${this.baseId}-errors`;\n }\n\n private get warningId(): string {\n return `${this.baseId}-warning`;\n }\n\n private get tipId(): string {\n return `${this.baseId}-tip`;\n }\n\n private get controlId(): string {\n return this.for || `${this.baseId}-control`;\n }\n\n private hasLabel(): boolean {\n return Boolean(this.label) || this.hasSlotController.test('label');\n }\n\n private hasInstructions(): boolean {\n return Boolean(this.instructions)\n || this.hasSlotController.test('instructions')\n || this.hasSlotController.test('hint');\n }\n\n private hasHeaderEnd(): boolean {\n return this.hasSlotController.test('header-end');\n }\n\n private hasErrors(): boolean {\n return this.errors.length > 0 || this.hasSlotController.test('errors');\n }\n\n private hasWarning(): boolean {\n return Boolean(this.warning) || this.hasSlotController.test('warning');\n }\n\n private hasTip(): boolean {\n return Boolean(this.tip) || this.hasSlotController.test('tip');\n }\n\n private getControlElement(): HTMLElement | null {\n const [control] = this.controlSlot?.assignedElements({ flatten: true }) ?? [];\n\n if (control instanceof HTMLElement) {\n return control;\n }\n\n if (this.for) {\n const root = this.getRootNode() as Document | ShadowRoot;\n return root.getElementById(this.for);\n }\n\n return null;\n }\n\n private focusControl(): void {\n const control = this.getControlElement();\n\n if (!control || typeof control.focus !== 'function') {\n return;\n }\n\n control.focus();\n }\n\n private onLabelClick = (event: MouseEvent): void => {\n const target = event.target;\n\n if (!(target instanceof Element)) {\n return;\n }\n\n if (target.closest('button, a, input, select, textarea, [role=\"button\"], [role=\"link\"]')) {\n return;\n }\n\n this.focusControl();\n };\n\n private syncControlAria(): void {\n const control = this.getControlElement();\n\n if (!control) {\n return;\n }\n\n syncFieldAria({\n control,\n labelId: this.labelId,\n instructionsId: this.instructionsId,\n errorsId: this.errorsId,\n warningId: this.warningId,\n tipId: this.tipId,\n controlId: this.controlId,\n hasLabel: this.hasLabel(),\n hasInstructions: this.hasInstructions(),\n hasErrors: this.hasErrors(),\n hasWarning: this.hasWarning(),\n hasTip: this.hasTip(),\n hasRequired: this.required,\n invalid: this.hasErrors(),\n });\n }\n\n private onControlSlotChange = (): void => {\n this.syncControlAria();\n this.requestUpdate();\n };\n\n override render() {\n const hasLabel = this.hasLabel();\n const hasInstructions = this.hasInstructions();\n const hasHeaderEnd = this.hasHeaderEnd();\n const hasErrors = this.hasErrors();\n const hasWarning = this.hasWarning();\n const hasTip = this.hasTip();\n const labelFor = this.for || (hasLabel ? this.controlId : nothing);\n\n return html`\n <div part=\"form-control\" class=\"form-control\">\n ${hasLabel || hasInstructions || hasHeaderEnd\n ? html`\n <div\n part=\"header\"\n class=${classMap({\n 'form-control__header': true,\n 'form-control__header--with-end': hasHeaderEnd,\n })}\n >\n <div class=\"form-control__header-main\">\n ${hasLabel\n ? html`\n <label\n part=\"label\"\n class=\"form-control__label\"\n id=${this.labelId}\n for=${labelFor}\n data-error=${hasErrors ? 'true' : nothing}\n @click=${this.onLabelClick}\n >\n <slot name=\"label\">${this.label}</slot>\n ${this.required\n ? html`\n <span class=\"sr-only\">Required</span>\n <span class=\"form-control__required\" aria-hidden=\"true\">\n ${createIconElement(asterisk)}\n </span>\n `\n : nothing}\n ${this.translatable\n ? html`\n <span class=\"form-control__translatable\" title=\"Translatable\">\n ${createTranslationIconElement()}\n <span class=\"sr-only\">Translatable</span>\n </span>\n `\n : nothing}\n </label>\n `\n : nothing}\n\n ${hasInstructions\n ? html`\n <p\n part=\"instructions\"\n class=\"form-control__instructions pk-inline-markdown\"\n id=${this.instructionsId}\n >\n <slot name=\"instructions\">${inlineMarkdown(this.instructions)}</slot>\n <slot name=\"hint\"></slot>\n </p>\n `\n : nothing}\n </div>\n\n ${hasHeaderEnd\n ? html`\n <div part=\"header-end\" class=\"form-control__header-end\">\n <slot name=\"header-end\"></slot>\n </div>\n `\n : html`<slot name=\"header-end\" hidden></slot>`}\n </div>\n `\n : nothing}\n\n <div part=\"control\" class=\"form-control__control\">\n <slot @slotchange=${this.onControlSlotChange}></slot>\n </div>\n\n ${hasErrors\n ? html`\n <ul part=\"errors\" class=\"form-control__errors pk-inline-markdown\" id=${this.errorsId}>\n ${this.errors.map((message) => html`<li>${inlineMarkdown(message)}</li>`)}\n <slot name=\"errors\"></slot>\n </ul>\n `\n : nothing}\n\n ${hasWarning\n ? html`\n <div part=\"warning\" class=\"form-control__warning\" id=${this.warningId}>\n <span class=\"form-control__warning-icon\" aria-hidden=\"true\">\n ${createIconElement(triangleExclamation)}\n </span>\n <p class=\"form-control__warning-text pk-inline-markdown\">\n <slot name=\"warning\">${inlineMarkdown(this.warning)}</slot>\n </p>\n </div>\n `\n : nothing}\n\n ${hasTip\n ? html`\n <div part=\"tip\" class=\"form-control__tip\" id=${this.tipId}>\n <span class=\"form-control__tip-icon\" aria-hidden=\"true\">\n ${createIconElement(lightbulb)}\n </span>\n <p class=\"form-control__tip-text pk-inline-markdown\">\n <span class=\"sr-only\">Tip: </span>\n <slot name=\"tip\">${inlineMarkdown(this.tip)}</slot>\n </p>\n </div>\n `\n : nothing}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'pk-field': PkField;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"pk-field-JFP24j4o.js","names":[],"sources":["../../src/base/markdown.styles.ts","../../src/internal/field-aria.ts","../../src/utils/inline-markdown.ts","../../src/components/field/pk-field.styles.ts","../../src/components/field/pk-field.ts"],"sourcesContent":["import { css } from 'lit';\n\n/** Shared inline markdown styling for field instructions, errors, and warnings. */\nexport const inlineMarkdownStyles = css`\n @layer pk-component {\n .pk-inline-markdown a {\n color: var(--pk-color-blue-500);\n text-decoration: none;\n }\n\n .pk-inline-markdown a:hover {\n text-decoration: underline;\n }\n\n /* Craft p code — gray chip; tip/warning/error override bg/border on pk-field. */\n .pk-inline-markdown code {\n /* Craft --border-hairline ≈ gray-800 @ 10%. */\n border: 1px solid color-mix(in srgb, var(--pk-color-gray-800) 10%, transparent);\n border-radius: var(--pk-radius-sm);\n background: var(--pk-color-gray-100);\n padding-block: 0.0625em;\n padding-inline: 0.25em;\n font-family: var(--pk-font-family-mono, ui-monospace, monospace);\n /* v1 field help/errors used [&_code]:text-[0.85em] — tighter than --pk-font-size-mono (0.9em). */\n font-size: var(--pk-inline-markdown-code-font-size, 0.85em);\n line-height: var(--pk-line-height-mono, 1.5);\n /* Inherit tip/warning/error/instructions text color (Craft parity). */\n color: inherit;\n }\n }\n`;\n","export type SyncFieldAriaOptions = {\n control: HTMLElement;\n labelId: string;\n instructionsId: string;\n errorsId: string;\n warningId: string;\n tipId: string;\n controlId: string;\n hasLabel: boolean;\n hasInstructions: boolean;\n hasErrors: boolean;\n hasWarning: boolean;\n hasTip: boolean;\n hasRequired?: boolean;\n invalid?: boolean;\n};\n\n/** Wires label/instructions/errors/warning/tip ids to a slotted field control. */\nexport function syncFieldAria({\n control,\n labelId,\n instructionsId,\n errorsId,\n warningId,\n tipId,\n controlId,\n hasLabel,\n hasInstructions,\n hasErrors,\n hasWarning,\n hasTip,\n hasRequired = false,\n invalid = false,\n}: SyncFieldAriaOptions): void {\n if (!control.id) {\n control.id = controlId;\n }\n\n if (hasLabel) {\n control.setAttribute('aria-labelledby', labelId);\n } else {\n control.removeAttribute('aria-labelledby');\n }\n\n const describedBy = [\n hasInstructions ? instructionsId : '',\n hasErrors ? errorsId : '',\n hasWarning ? warningId : '',\n hasTip ? tipId : '',\n ].filter(Boolean);\n\n if (describedBy.length > 0) {\n control.setAttribute('aria-describedby', describedBy.join(' '));\n } else {\n control.removeAttribute('aria-describedby');\n }\n\n if (hasRequired) {\n control.setAttribute('aria-required', 'true');\n } else {\n control.removeAttribute('aria-required');\n }\n\n // Kit controls (pk-input, etc.) paint error chrome from reflected `invalid`.\n // v1 Input used Tailwind `aria-invalid:border-*` — aria alone is not enough now.\n const isInvalid = Boolean(invalid || hasErrors);\n\n if (isInvalid) {\n control.setAttribute('aria-invalid', 'true');\n control.setAttribute('aria-errormessage', errorsId);\n } else {\n control.removeAttribute('aria-invalid');\n control.removeAttribute('aria-errormessage');\n }\n\n syncControlInvalidState(control, isInvalid);\n}\n\n/** Prefer the Lit `invalid` property when present; otherwise toggle the attribute. */\nfunction syncControlInvalidState(control: HTMLElement, isInvalid: boolean): void {\n if ('invalid' in control) {\n (control as HTMLElement & { invalid: boolean }).invalid = isInvalid;\n return;\n }\n\n control.toggleAttribute('invalid', isInvalid);\n}\n","import { renderInlineMarkdown } from '@verbb/plugin-kit-core';\nimport { nothing } from 'lit';\nimport { unsafeHTML, type UnsafeHTMLDirective } from 'lit/directives/unsafe-html.js';\nimport type { DirectiveResult } from 'lit/directive.js';\n\n/** Renders inline markdown for Lit templates (bold, italic, links, code). */\nexport function inlineMarkdown(content: string): DirectiveResult<typeof UnsafeHTMLDirective> | typeof nothing {\n if (!content) {\n return nothing;\n }\n\n const html = renderInlineMarkdown(content);\n\n if (!html) {\n return nothing;\n }\n\n return unsafeHTML(html);\n}\n","import { css } from 'lit';\n\nexport const pkFieldStyles = css`\n @layer pk-component {\n :host {\n display: block;\n width: 100%;\n }\n\n .form-control__control {\n display: block;\n position: relative;\n width: 100%;\n }\n\n .form-control__header--with-end {\n flex-direction: row;\n align-items: flex-start;\n justify-content: space-between;\n gap: 0.75rem;\n }\n\n .form-control__header-main {\n display: flex;\n flex-direction: column;\n gap: 0.125rem;\n min-width: 0;\n flex: 1 1 auto;\n }\n\n .form-control__header-end {\n flex-shrink: 0;\n }\n\n .form-control__required {\n display: inline-flex;\n align-items: center;\n color: var(--pk-color-rose-600);\n line-height: 0;\n }\n\n .form-control__required svg {\n display: block;\n width: 10px;\n height: 10px;\n }\n\n .form-control__translatable {\n display: inline-flex;\n align-items: center;\n color: var(--pk-color-gray-550);\n line-height: 0;\n }\n\n .form-control__translatable svg {\n display: block;\n width: 1rem;\n height: 1rem;\n fill: currentColor;\n }\n\n .form-control__errors {\n margin: 0;\n padding-inline-start: 20px;\n color: var(--pk-color-error);\n font-family: var(--pk-font-family);\n font-size: var(--pk-font-size-base);\n line-height: var(--pk-line-height);\n list-style: square;\n }\n\n .form-control__errors:empty {\n display: none;\n }\n\n .form-control__warning {\n display: flex;\n align-items: flex-start;\n gap: 0.25rem;\n min-width: 0;\n margin: 0;\n color: var(--pk-color-warning);\n font-family: var(--pk-font-family);\n font-size: var(--pk-font-size-base);\n line-height: var(--pk-line-height);\n }\n\n .form-control__warning:empty {\n display: none;\n }\n\n .form-control__warning-icon {\n display: inline-flex;\n flex-shrink: 0;\n margin-top: 0.3em;\n width: 0.75rem;\n height: 0.75rem;\n line-height: 0;\n }\n\n .form-control__warning-text {\n min-width: 0;\n margin: 0;\n }\n\n .form-control__warning-icon svg {\n display: block;\n width: 100%;\n height: 100%;\n }\n\n /* Craft .warning code — amber chip matching warning text. */\n .form-control__warning .pk-inline-markdown code {\n background-color: var(--pk-color-amber-100);\n border-color: var(--pk-color-amber-300);\n }\n\n .form-control__tip {\n display: flex;\n align-items: flex-start;\n gap: 0.25rem;\n min-width: 0;\n margin: 0;\n color: var(--pk-color-sky-700);\n font-family: var(--pk-font-family);\n font-size: var(--pk-font-size-base);\n line-height: var(--pk-line-height);\n }\n\n .form-control__tip:empty {\n display: none;\n }\n\n .form-control__tip-icon {\n display: inline-flex;\n flex-shrink: 0;\n margin-top: 0.3em;\n width: 0.75rem;\n height: 0.75rem;\n line-height: 0;\n }\n\n .form-control__tip-text {\n min-width: 0;\n margin: 0;\n }\n\n .form-control__tip-icon svg {\n display: block;\n width: 100%;\n height: 100%;\n }\n\n .form-control__tip-text a {\n text-decoration: underline;\n }\n\n /* Craft .tip code — sky/notice chip matching tip text. */\n .form-control__tip .pk-inline-markdown code {\n background-color: var(--pk-color-sky-100);\n border-color: var(--pk-color-sky-300);\n }\n\n /* Craft --bg-error / --border-error pattern for field errors. */\n .form-control__errors.pk-inline-markdown code {\n background-color: var(--pk-color-red-100);\n border-color: var(--pk-color-red-300);\n }\n }\n`;\n","import { html, nothing } from 'lit';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { customElement, property, query } from 'lit/decorators.js';\nimport type { PropertyValues } from 'lit';\n\nimport { uniqueId } from '../../a11y/focus.js';\nimport { formControlStyles } from '../../base/form-control.styles.js';\nimport { inlineMarkdownStyles } from '../../base/markdown.styles.js';\nimport { PkElement } from '../../base/pk-element.js';\nimport { createIconElement, createTranslationIconElement, asterisk, lightbulb, triangleExclamation } from '../../icons/index.js';\nimport { syncFieldAria } from '../../internal/field-aria.js';\nimport { HasSlotController } from '../../internal/has-slot.js';\nimport { inlineMarkdown } from '../../utils/inline-markdown.js';\nimport { pkFieldStyles } from './pk-field.styles.js';\n\n/**\n * Form field shell — label, instructions, errors, warning, and tip around a slotted control.\n *\n * Mirrors Plugin Kit React `FieldLayout`. Use for schema-driven forms; controls may\n * also expose their own `label` / `instructions` for standalone usage.\n *\n * @slot label - Field label\n * @slot instructions - Help text below the label (property values support inline Markdown)\n * @slot hint - Alias for `instructions`\n * @slot header-end - Extra header actions (React `headerEnd`)\n * @slot errors - Custom error content (property values support inline Markdown)\n * @slot warning - Warning message (property values support inline Markdown)\n * @slot tip - Informational tip below the control (property values support inline Markdown)\n * @slot - Field control (`pk-input`, `pk-select`, etc.)\n *\n * @csspart header - Field header row\n * @csspart header-end - Trailing header actions\n * @csspart form-control - Root wrapper\n * @csspart label - Label element\n * @csspart control - Control slot wrapper\n * @csspart instructions - Instructions region\n * @csspart errors - Errors list\n * @csspart warning - Warning region\n * @csspart tip - Tip region\n */\n@customElement('pk-field')\nexport class PkField extends PkElement {\n static override styles = [formControlStyles, inlineMarkdownStyles, pkFieldStyles];\n\n private readonly hasSlotController = new HasSlotController(\n this,\n 'label',\n 'instructions',\n 'hint',\n 'header-end',\n 'warning',\n 'tip',\n 'errors',\n );\n\n private readonly baseId = uniqueId('pk-field');\n\n @property()\n label = '';\n\n @property()\n instructions = '';\n\n @property({ type: Boolean, reflect: true })\n required = false;\n\n /** Shows the translatable-field icon beside the label. */\n @property({ type: Boolean, reflect: true })\n translatable = false;\n\n @property()\n warning = '';\n\n @property()\n tip = '';\n\n @property({ attribute: false })\n errors: string[] = [];\n\n /** Associates the label with a control id in the light DOM. */\n @property({ reflect: true })\n for = '';\n\n @query('slot:not([name])')\n private controlSlot!: HTMLSlotElement;\n\n override connectedCallback(): void {\n super.connectedCallback();\n\n const legacyHint = this.getAttribute('hint');\n\n if (legacyHint && !this.instructions) {\n this.instructions = legacyHint;\n }\n }\n\n override updated(changed: PropertyValues): void {\n super.updated(changed);\n\n if (\n changed.has('label')\n || changed.has('instructions')\n || changed.has('errors')\n || changed.has('warning')\n || changed.has('tip')\n || changed.has('required')\n || changed.has('for')\n ) {\n this.syncControlAria();\n }\n }\n\n private get labelId(): string {\n return `${this.baseId}-label`;\n }\n\n private get instructionsId(): string {\n return `${this.baseId}-instructions`;\n }\n\n private get errorsId(): string {\n return `${this.baseId}-errors`;\n }\n\n private get warningId(): string {\n return `${this.baseId}-warning`;\n }\n\n private get tipId(): string {\n return `${this.baseId}-tip`;\n }\n\n private get controlId(): string {\n return this.for || `${this.baseId}-control`;\n }\n\n private hasLabel(): boolean {\n return Boolean(this.label) || this.hasSlotController.test('label');\n }\n\n private hasInstructions(): boolean {\n return Boolean(this.instructions)\n || this.hasSlotController.test('instructions')\n || this.hasSlotController.test('hint');\n }\n\n private hasHeaderEnd(): boolean {\n return this.hasSlotController.test('header-end');\n }\n\n private hasErrors(): boolean {\n return this.errors.length > 0 || this.hasSlotController.test('errors');\n }\n\n private hasWarning(): boolean {\n return Boolean(this.warning) || this.hasSlotController.test('warning');\n }\n\n private hasTip(): boolean {\n return Boolean(this.tip) || this.hasSlotController.test('tip');\n }\n\n private getControlElement(): HTMLElement | null {\n const [control] = this.controlSlot?.assignedElements({ flatten: true }) ?? [];\n\n if (control instanceof HTMLElement) {\n return control;\n }\n\n if (this.for) {\n const root = this.getRootNode() as Document | ShadowRoot;\n return root.getElementById(this.for);\n }\n\n return null;\n }\n\n private focusControl(): void {\n const control = this.getControlElement();\n\n if (!control || typeof control.focus !== 'function') {\n return;\n }\n\n control.focus();\n }\n\n private onLabelClick = (event: MouseEvent): void => {\n const target = event.target;\n\n if (!(target instanceof Element)) {\n return;\n }\n\n if (target.closest('button, a, input, select, textarea, [role=\"button\"], [role=\"link\"]')) {\n return;\n }\n\n this.focusControl();\n };\n\n private syncControlAria(): void {\n const control = this.getControlElement();\n\n if (!control) {\n return;\n }\n\n syncFieldAria({\n control,\n labelId: this.labelId,\n instructionsId: this.instructionsId,\n errorsId: this.errorsId,\n warningId: this.warningId,\n tipId: this.tipId,\n controlId: this.controlId,\n hasLabel: this.hasLabel(),\n hasInstructions: this.hasInstructions(),\n hasErrors: this.hasErrors(),\n hasWarning: this.hasWarning(),\n hasTip: this.hasTip(),\n hasRequired: this.required,\n invalid: this.hasErrors(),\n });\n }\n\n private onControlSlotChange = (): void => {\n this.syncControlAria();\n this.requestUpdate();\n };\n\n override render() {\n const hasLabel = this.hasLabel();\n const hasInstructions = this.hasInstructions();\n const hasHeaderEnd = this.hasHeaderEnd();\n const hasErrors = this.hasErrors();\n const hasWarning = this.hasWarning();\n const hasTip = this.hasTip();\n const labelFor = this.for || (hasLabel ? this.controlId : nothing);\n\n return html`\n <div part=\"form-control\" class=\"form-control\">\n ${hasLabel || hasInstructions || hasHeaderEnd\n ? html`\n <div\n part=\"header\"\n class=${classMap({\n 'form-control__header': true,\n 'form-control__header--with-end': hasHeaderEnd,\n })}\n >\n <div class=\"form-control__header-main\">\n ${hasLabel\n ? html`\n <label\n part=\"label\"\n class=\"form-control__label\"\n id=${this.labelId}\n for=${labelFor}\n data-error=${hasErrors ? 'true' : nothing}\n @click=${this.onLabelClick}\n >\n <slot name=\"label\">${this.label}</slot>\n ${this.required\n ? html`\n <span class=\"sr-only\">Required</span>\n <span class=\"form-control__required\" aria-hidden=\"true\">\n ${createIconElement(asterisk)}\n </span>\n `\n : nothing}\n ${this.translatable\n ? html`\n <span class=\"form-control__translatable\" title=\"Translatable\">\n ${createTranslationIconElement()}\n <span class=\"sr-only\">Translatable</span>\n </span>\n `\n : nothing}\n </label>\n `\n : nothing}\n\n ${hasInstructions\n ? html`\n <p\n part=\"instructions\"\n class=\"form-control__instructions pk-inline-markdown\"\n id=${this.instructionsId}\n >\n <slot name=\"instructions\">${inlineMarkdown(this.instructions)}</slot>\n <slot name=\"hint\"></slot>\n </p>\n `\n : nothing}\n </div>\n\n ${hasHeaderEnd\n ? html`\n <div part=\"header-end\" class=\"form-control__header-end\">\n <slot name=\"header-end\"></slot>\n </div>\n `\n : html`<slot name=\"header-end\" hidden></slot>`}\n </div>\n `\n : nothing}\n\n <div part=\"control\" class=\"form-control__control\">\n <slot @slotchange=${this.onControlSlotChange}></slot>\n </div>\n\n ${hasErrors\n ? html`\n <ul part=\"errors\" class=\"form-control__errors pk-inline-markdown\" id=${this.errorsId}>\n ${this.errors.map((message) => html`<li>${inlineMarkdown(message)}</li>`)}\n <slot name=\"errors\"></slot>\n </ul>\n `\n : nothing}\n\n ${hasWarning\n ? html`\n <div part=\"warning\" class=\"form-control__warning\" id=${this.warningId}>\n <span class=\"form-control__warning-icon\" aria-hidden=\"true\">\n ${createIconElement(triangleExclamation)}\n </span>\n <p class=\"form-control__warning-text pk-inline-markdown\">\n <slot name=\"warning\">${inlineMarkdown(this.warning)}</slot>\n </p>\n </div>\n `\n : nothing}\n\n ${hasTip\n ? html`\n <div part=\"tip\" class=\"form-control__tip\" id=${this.tipId}>\n <span class=\"form-control__tip-icon\" aria-hidden=\"true\">\n ${createIconElement(lightbulb)}\n </span>\n <p class=\"form-control__tip-text pk-inline-markdown\">\n <span class=\"sr-only\">Tip: </span>\n <slot name=\"tip\">${inlineMarkdown(this.tip)}</slot>\n </p>\n </div>\n `\n : nothing}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'pk-field': PkField;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pk-option-C-cR-jOv.js","names":[],"sources":["../../src/utils/highlight-text.ts","../../src/components/select/pk-option.styles.ts","../../src/components/select/pk-option.ts"],"sourcesContent":["export type HighlightPart = {\n text: string;\n match: boolean;\n};\n\n/** Split label text into matched/unmatched segments for typeahead highlighting. */\nexport function splitHighlightParts(text: string, search: string): HighlightPart[] {\n const label = String(text ?? '');\n const query = String(search ?? '').trim();\n\n if (!query) {\n return [{ text: label, match: false }];\n }\n\n const lowerLabel = label.toLowerCase();\n const lowerQuery = query.toLowerCase();\n const parts: HighlightPart[] = [];\n let cursor = 0;\n let matchIndex = lowerLabel.indexOf(lowerQuery);\n\n while (matchIndex !== -1) {\n if (matchIndex > cursor) {\n parts.push({\n text: label.slice(cursor, matchIndex),\n match: false,\n });\n }\n\n parts.push({\n text: label.slice(matchIndex, matchIndex + query.length),\n match: true,\n });\n\n cursor = matchIndex + query.length;\n matchIndex = lowerLabel.indexOf(lowerQuery, cursor);\n }\n\n if (cursor < label.length) {\n parts.push({\n text: label.slice(cursor),\n match: false,\n });\n }\n\n return parts.length > 0 ? parts : [{ text: label, match: false }];\n}\n","import { css } from 'lit';\n\nexport const pkOptionStyles = css`\n @layer pk-component {\n :host {\n display: block;\n /*\n * Slotted option labels inherit type metrics from this host (same\n * Craft-vs-Tailwind trap as pk-dropdown-item). Size tokens arrive via\n * pk-select ::slotted(pk-option) custom properties.\n */\n font-family: var(--pk-font-family);\n font-size: var(--pk-select-item-font-size, var(--pk-font-size-base));\n line-height: var(--pk-select-item-line-height, 1.4);\n color: var(--pk-color-gray-700);\n }\n\n .option {\n position: relative;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n width: 100%;\n margin: 0;\n min-height: var(--pk-select-item-min-height, var(--pk-input-height));\n padding-block: var(--pk-select-item-padding-block, 6px);\n padding-inline-start: var(--pk-select-item-padding-inline, 10px);\n padding-inline-end: var(--pk-select-item-padding-inline-end, 2rem);\n border: var(--pk-select-trigger-border-width, 1px) solid transparent;\n background: transparent;\n color: inherit;\n font: inherit;\n font-family: var(--pk-font-family);\n font-size: var(--pk-select-item-font-size, var(--pk-font-size-base));\n line-height: var(--pk-select-item-line-height, 1.4);\n text-align: left;\n white-space: nowrap;\n cursor: default;\n user-select: none;\n outline: none;\n box-sizing: border-box;\n }\n\n .start {\n display: none;\n flex: 0 0 auto;\n align-items: center;\n }\n\n :host([data-has-start]) .start {\n display: inline-flex;\n }\n\n :host([hidden]) {\n display: none !important;\n }\n\n .option:focus-visible,\n :host([highlighted]) .option {\n background: var(--pk-color-slate-100);\n }\n\n :host([disabled]) .option,\n .option[aria-disabled='true'] {\n pointer-events: none;\n opacity: 0.5;\n }\n\n .check {\n position: absolute;\n inset-inline-end: var(--pk-select-item-indicator-inset, 0.5rem);\n top: 50%;\n display: none;\n align-items: center;\n justify-content: center;\n width: var(--pk-select-item-indicator-size, 0.75rem);\n height: var(--pk-select-item-indicator-size, 0.75rem);\n color: var(--pk-color-gray-700);\n pointer-events: none;\n transform: translateY(-50%);\n line-height: 0;\n }\n\n :host([selected]) .check {\n display: inline-flex;\n }\n\n .check svg {\n display: block;\n width: var(--pk-select-item-indicator-size, 0.75rem);\n height: var(--pk-select-item-indicator-size, 0.75rem);\n flex-shrink: 0;\n pointer-events: none;\n }\n\n .label {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n /* Allow custom multi-line option layouts (title + subtitle) to stack. */\n white-space: normal;\n }\n\n .match {\n padding: 0;\n border-radius: 2px;\n background: var(--pk-color-blue-100);\n color: inherit;\n }\n }\n`;\n","import { html, nothing } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { unsafeSVG } from 'lit/directives/unsafe-svg.js';\n\nimport { check, renderIconHtml } from '../../icons/index.js';\nimport { PkElement } from '../../base/pk-element.js';\nimport { splitHighlightParts } from '../../utils/highlight-text.js';\nimport { pkOptionStyles } from './pk-option.styles.js';\n\nconst CHECK_ICON = renderIconHtml(check);\n\n/**\n * Select option — use inside `pk-select` or `pk-combobox`.\n *\n * @slot start - Presentational decoration before the label (e.g. `pk-status`).\n * @slot - Option label\n *\n * @csspart start - Start decoration container\n * @csspart option - Option button\n * @csspart label - Option label\n * @csspart check - Selected-state check indicator\n */\n@customElement('pk-option')\nexport class PkOption extends PkElement {\n static override styles = pkOptionStyles;\n\n @property()\n value = '';\n\n /**\n * Optional short label for the closed trigger / filter identity (v1 itemToStringLabel).\n * When set, preferred over concatenating rich default-slot text (title + subtitle).\n */\n @property()\n label = '';\n\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n @property({ type: Boolean, reflect: true })\n selected = false;\n\n @property({ type: Boolean, reflect: true })\n highlighted = false;\n\n @property({ type: Boolean, reflect: true })\n hidden = false;\n\n @property({ type: Number, attribute: 'focus-index' })\n focusIndex = -1;\n\n @property()\n optionId = '';\n\n /** When set, the label renders with matching query text highlighted (combobox filter). */\n @property({ attribute: false })\n matchQuery = '';\n\n focusControl(preventScroll = true): void {\n this.shadowRoot?.querySelector<HTMLButtonElement>('.option')?.focus({ preventScroll });\n }\n\n /**\n * Label for the closed combobox/select value.\n * Prefers the `label` attribute when set; otherwise default-slot text\n * (excluding `slot=\"start\"`), joined with spaces for multi-node layouts.\n */\n getLabel(): string {\n if (this.label.trim()) {\n return this.label.trim();\n }\n\n const labelSlot = this.shadowRoot?.querySelector<HTMLSlotElement>('slot:not([name])');\n\n if (!labelSlot) {\n return this.textContent?.trim() ?? this.value;\n }\n\n // Join with spaces so multi-line custom labels (\"Link\" + \"Craft CMS\") do not\n // concatenate into \"LinkCraft CMS\" when no explicit `label` is set.\n return labelSlot.assignedNodes()\n .map((node) => (node.textContent ?? '').trim())\n .filter(Boolean)\n .join(' ')\n .trim();\n }\n\n /** Full default-slot text for typeahead matching (includes subtitle lines). */\n getSearchText(): string {\n const labelSlot = this.shadowRoot?.querySelector<HTMLSlotElement>('slot:not([name])');\n\n if (!labelSlot) {\n return this.getLabel();\n }\n\n const fromSlot = labelSlot.assignedNodes()\n .map((node) => (node.textContent ?? '').trim())\n .filter(Boolean)\n .join(' ')\n .trim();\n\n return fromSlot || this.getLabel();\n }\n\n /** True when the default slot has element children (custom multi-line / rich layouts). */\n private hasRichLabelContent(): boolean {\n return [...this.children].some((node) => {\n if (!(node instanceof HTMLElement)) {\n return false;\n }\n\n // Named slots (e.g. start) are not part of the label.\n return !node.slot || node.slot === '';\n });\n }\n\n /** Light-DOM elements assigned to the start decoration slot. */\n getStartElements(): HTMLElement[] {\n return [...this.querySelectorAll(':scope > [slot=\"start\"]')].filter(\n (node): node is HTMLElement => node instanceof HTMLElement,\n );\n }\n\n override firstUpdated(): void {\n const startSlot = this.shadowRoot?.querySelector<HTMLSlotElement>('slot[name=\"start\"]');\n\n startSlot?.addEventListener('slotchange', () => this.syncStartDecoration());\n this.syncStartDecoration();\n }\n\n private syncStartDecoration(): void {\n this.toggleAttribute('data-has-start', this.getStartElements().length > 0);\n }\n\n private handleClick(): void {\n if (this.disabled) {\n return;\n }\n\n this.dispatchEvent(new CustomEvent('pk-option-select', {\n detail: { value: this.value },\n bubbles: true,\n composed: true,\n }));\n }\n\n private handleMouseEnter(): void {\n if (this.disabled || this.hidden) {\n return;\n }\n\n this.dispatchEvent(new CustomEvent('pk-option-highlight', {\n detail: { value: this.value },\n bubbles: true,\n composed: true,\n }));\n }\n\n private handleKeyDown(event: KeyboardEvent): void {\n const navKeys = new Set([\n 'ArrowDown',\n 'ArrowUp',\n 'ArrowLeft',\n 'ArrowRight',\n 'Home',\n 'End',\n 'Enter',\n ' ',\n 'Escape',\n ]);\n\n if (!navKeys.has(event.key)) {\n return;\n }\n\n const owner = this.closest('pk-select, pk-combobox');\n const panel = owner ? null : this.closest('[role=\"listbox\"]');\n\n if (!owner && !panel) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n\n const keydownEvent = new CustomEvent('pk-listbox-keydown', {\n detail: { keyboardEvent: event },\n bubbles: true,\n });\n\n if (owner) {\n owner.dispatchEvent(keydownEvent);\n return;\n }\n\n panel!.dispatchEvent(keydownEvent);\n }\n\n private renderLabel() {\n const query = this.matchQuery.trim();\n // Flat highlight replaces the default slot — that collapses custom layouts\n // (title + subtitle) into one run when filtering. Keep the slot for rich content.\n if (!query || this.hasRichLabelContent()) {\n return html`\n <span part=\"label\" class=\"label\">\n <slot></slot>\n </span>\n `;\n }\n\n const label = this.getLabel();\n const parts = splitHighlightParts(label, query);\n\n return html`\n <span part=\"label\" class=\"label\">\n ${parts.map((part) => part.match\n ? html`<mark class=\"match\">${part.text}</mark>`\n : html`<span>${part.text}</span>`)}\n </span>\n `;\n }\n\n override render() {\n return html`\n <button\n part=\"option\"\n type=\"button\"\n class=\"option\"\n role=\"option\"\n id=${this.optionId || nothing}\n ?disabled=${this.disabled}\n aria-disabled=${this.disabled ? 'true' : nothing}\n aria-selected=${this.selected ? 'true' : 'false'}\n tabindex=${this.focusIndex}\n @click=${this.handleClick}\n @mouseenter=${this.handleMouseEnter}\n @keydown=${this.handleKeyDown}\n >\n <span part=\"start\" class=\"start\">\n <slot name=\"start\"></slot>\n </span>\n ${this.renderLabel()}\n <span part=\"check\" class=\"check\" aria-hidden=\"true\">${unsafeSVG(CHECK_ICON)}</span>\n </button>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'pk-option': PkOption;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"pk-option-Cy7oOcwF.js","names":[],"sources":["../../src/utils/highlight-text.ts","../../src/components/select/pk-option.styles.ts","../../src/components/select/pk-option.ts"],"sourcesContent":["export type HighlightPart = {\n text: string;\n match: boolean;\n};\n\n/** Split label text into matched/unmatched segments for typeahead highlighting. */\nexport function splitHighlightParts(text: string, search: string): HighlightPart[] {\n const label = String(text ?? '');\n const query = String(search ?? '').trim();\n\n if (!query) {\n return [{ text: label, match: false }];\n }\n\n const lowerLabel = label.toLowerCase();\n const lowerQuery = query.toLowerCase();\n const parts: HighlightPart[] = [];\n let cursor = 0;\n let matchIndex = lowerLabel.indexOf(lowerQuery);\n\n while (matchIndex !== -1) {\n if (matchIndex > cursor) {\n parts.push({\n text: label.slice(cursor, matchIndex),\n match: false,\n });\n }\n\n parts.push({\n text: label.slice(matchIndex, matchIndex + query.length),\n match: true,\n });\n\n cursor = matchIndex + query.length;\n matchIndex = lowerLabel.indexOf(lowerQuery, cursor);\n }\n\n if (cursor < label.length) {\n parts.push({\n text: label.slice(cursor),\n match: false,\n });\n }\n\n return parts.length > 0 ? parts : [{ text: label, match: false }];\n}\n","import { css } from 'lit';\n\nexport const pkOptionStyles = css`\n @layer pk-component {\n :host {\n display: block;\n /*\n * Slotted option labels inherit type metrics from this host (same\n * Craft-vs-Tailwind trap as pk-dropdown-item). Size tokens arrive via\n * pk-select ::slotted(pk-option) custom properties.\n */\n font-family: var(--pk-font-family);\n font-size: var(--pk-select-item-font-size, var(--pk-font-size-base));\n line-height: var(--pk-select-item-line-height, 1.4);\n color: var(--pk-color-gray-700);\n }\n\n .option {\n position: relative;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n width: 100%;\n margin: 0;\n min-height: var(--pk-select-item-min-height, var(--pk-input-height));\n padding-block: var(--pk-select-item-padding-block, 6px);\n padding-inline-start: var(--pk-select-item-padding-inline, 10px);\n padding-inline-end: var(--pk-select-item-padding-inline-end, 2rem);\n border: var(--pk-select-trigger-border-width, 1px) solid transparent;\n background: transparent;\n color: inherit;\n font: inherit;\n font-family: var(--pk-font-family);\n font-size: var(--pk-select-item-font-size, var(--pk-font-size-base));\n line-height: var(--pk-select-item-line-height, 1.4);\n text-align: left;\n white-space: nowrap;\n cursor: default;\n user-select: none;\n outline: none;\n box-sizing: border-box;\n }\n\n .start {\n display: none;\n flex: 0 0 auto;\n align-items: center;\n }\n\n :host([data-has-start]) .start {\n display: inline-flex;\n }\n\n :host([hidden]) {\n display: none !important;\n }\n\n .option:focus-visible,\n :host([highlighted]) .option {\n background: var(--pk-color-slate-100);\n }\n\n :host([disabled]) .option,\n .option[aria-disabled='true'] {\n pointer-events: none;\n opacity: 0.5;\n }\n\n .check {\n position: absolute;\n inset-inline-end: var(--pk-select-item-indicator-inset, 0.5rem);\n top: 50%;\n display: none;\n align-items: center;\n justify-content: center;\n width: var(--pk-select-item-indicator-size, 0.75rem);\n height: var(--pk-select-item-indicator-size, 0.75rem);\n color: var(--pk-color-gray-700);\n pointer-events: none;\n transform: translateY(-50%);\n line-height: 0;\n }\n\n :host([selected]) .check {\n display: inline-flex;\n }\n\n .check svg {\n display: block;\n width: var(--pk-select-item-indicator-size, 0.75rem);\n height: var(--pk-select-item-indicator-size, 0.75rem);\n flex-shrink: 0;\n pointer-events: none;\n }\n\n .label {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n /* Allow custom multi-line option layouts (title + subtitle) to stack. */\n white-space: normal;\n }\n\n .match {\n padding: 0;\n border-radius: 2px;\n background: var(--pk-color-blue-100);\n color: inherit;\n }\n }\n`;\n","import { html, nothing } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { unsafeSVG } from 'lit/directives/unsafe-svg.js';\n\nimport { check, renderIconHtml } from '../../icons/index.js';\nimport { PkElement } from '../../base/pk-element.js';\nimport { splitHighlightParts } from '../../utils/highlight-text.js';\nimport { pkOptionStyles } from './pk-option.styles.js';\n\nconst CHECK_ICON = renderIconHtml(check);\n\n/**\n * Select option — use inside `pk-select` or `pk-combobox`.\n *\n * @slot start - Presentational decoration before the label (e.g. `pk-status`).\n * @slot - Option label\n *\n * @csspart start - Start decoration container\n * @csspart option - Option button\n * @csspart label - Option label\n * @csspart check - Selected-state check indicator\n */\n@customElement('pk-option')\nexport class PkOption extends PkElement {\n static override styles = pkOptionStyles;\n\n @property()\n value = '';\n\n /**\n * Optional short label for the closed trigger / filter identity (v1 itemToStringLabel).\n * When set, preferred over concatenating rich default-slot text (title + subtitle).\n */\n @property()\n label = '';\n\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n @property({ type: Boolean, reflect: true })\n selected = false;\n\n @property({ type: Boolean, reflect: true })\n highlighted = false;\n\n @property({ type: Boolean, reflect: true })\n hidden = false;\n\n @property({ type: Number, attribute: 'focus-index' })\n focusIndex = -1;\n\n @property()\n optionId = '';\n\n /** When set, the label renders with matching query text highlighted (combobox filter). */\n @property({ attribute: false })\n matchQuery = '';\n\n focusControl(preventScroll = true): void {\n this.shadowRoot?.querySelector<HTMLButtonElement>('.option')?.focus({ preventScroll });\n }\n\n /**\n * Label for the closed combobox/select value.\n * Prefers the `label` attribute when set; otherwise default-slot text\n * (excluding `slot=\"start\"`), joined with spaces for multi-node layouts.\n */\n getLabel(): string {\n if (this.label.trim()) {\n return this.label.trim();\n }\n\n const labelSlot = this.shadowRoot?.querySelector<HTMLSlotElement>('slot:not([name])');\n\n if (!labelSlot) {\n return this.textContent?.trim() ?? this.value;\n }\n\n // Join with spaces so multi-line custom labels (\"Link\" + \"Craft CMS\") do not\n // concatenate into \"LinkCraft CMS\" when no explicit `label` is set.\n return labelSlot.assignedNodes()\n .map((node) => (node.textContent ?? '').trim())\n .filter(Boolean)\n .join(' ')\n .trim();\n }\n\n /** Full default-slot text for typeahead matching (includes subtitle lines). */\n getSearchText(): string {\n const labelSlot = this.shadowRoot?.querySelector<HTMLSlotElement>('slot:not([name])');\n\n if (!labelSlot) {\n return this.getLabel();\n }\n\n const fromSlot = labelSlot.assignedNodes()\n .map((node) => (node.textContent ?? '').trim())\n .filter(Boolean)\n .join(' ')\n .trim();\n\n return fromSlot || this.getLabel();\n }\n\n /** True when the default slot has element children (custom multi-line / rich layouts). */\n private hasRichLabelContent(): boolean {\n return [...this.children].some((node) => {\n if (!(node instanceof HTMLElement)) {\n return false;\n }\n\n // Named slots (e.g. start) are not part of the label.\n return !node.slot || node.slot === '';\n });\n }\n\n /** Light-DOM elements assigned to the start decoration slot. */\n getStartElements(): HTMLElement[] {\n return [...this.querySelectorAll(':scope > [slot=\"start\"]')].filter(\n (node): node is HTMLElement => node instanceof HTMLElement,\n );\n }\n\n override firstUpdated(): void {\n const startSlot = this.shadowRoot?.querySelector<HTMLSlotElement>('slot[name=\"start\"]');\n\n startSlot?.addEventListener('slotchange', () => this.syncStartDecoration());\n this.syncStartDecoration();\n }\n\n private syncStartDecoration(): void {\n this.toggleAttribute('data-has-start', this.getStartElements().length > 0);\n }\n\n private handleClick(): void {\n if (this.disabled) {\n return;\n }\n\n this.dispatchEvent(new CustomEvent('pk-option-select', {\n detail: { value: this.value },\n bubbles: true,\n composed: true,\n }));\n }\n\n private handleMouseEnter(): void {\n if (this.disabled || this.hidden) {\n return;\n }\n\n this.dispatchEvent(new CustomEvent('pk-option-highlight', {\n detail: { value: this.value },\n bubbles: true,\n composed: true,\n }));\n }\n\n private handleKeyDown(event: KeyboardEvent): void {\n const navKeys = new Set([\n 'ArrowDown',\n 'ArrowUp',\n 'ArrowLeft',\n 'ArrowRight',\n 'Home',\n 'End',\n 'Enter',\n ' ',\n 'Escape',\n ]);\n\n if (!navKeys.has(event.key)) {\n return;\n }\n\n const owner = this.closest('pk-select, pk-combobox');\n const panel = owner ? null : this.closest('[role=\"listbox\"]');\n\n if (!owner && !panel) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n\n const keydownEvent = new CustomEvent('pk-listbox-keydown', {\n detail: { keyboardEvent: event },\n bubbles: true,\n });\n\n if (owner) {\n owner.dispatchEvent(keydownEvent);\n return;\n }\n\n panel!.dispatchEvent(keydownEvent);\n }\n\n private renderLabel() {\n const query = this.matchQuery.trim();\n // Flat highlight replaces the default slot — that collapses custom layouts\n // (title + subtitle) into one run when filtering. Keep the slot for rich content.\n if (!query || this.hasRichLabelContent()) {\n return html`\n <span part=\"label\" class=\"label\">\n <slot></slot>\n </span>\n `;\n }\n\n const label = this.getLabel();\n const parts = splitHighlightParts(label, query);\n\n return html`\n <span part=\"label\" class=\"label\">\n ${parts.map((part) => part.match\n ? html`<mark class=\"match\">${part.text}</mark>`\n : html`<span>${part.text}</span>`)}\n </span>\n `;\n }\n\n override render() {\n return html`\n <button\n part=\"option\"\n type=\"button\"\n class=\"option\"\n role=\"option\"\n id=${this.optionId || nothing}\n ?disabled=${this.disabled}\n aria-disabled=${this.disabled ? 'true' : nothing}\n aria-selected=${this.selected ? 'true' : 'false'}\n tabindex=${this.focusIndex}\n @click=${this.handleClick}\n @mouseenter=${this.handleMouseEnter}\n @keydown=${this.handleKeyDown}\n >\n <span part=\"start\" class=\"start\">\n <slot name=\"start\"></slot>\n </span>\n ${this.renderLabel()}\n <span part=\"check\" class=\"check\" aria-hidden=\"true\">${unsafeSVG(CHECK_ICON)}</span>\n </button>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'pk-option': PkOption;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pk-option-group-
|
|
1
|
+
{"version":3,"file":"pk-option-group-BAFSIZTa.js","names":[],"sources":["../../src/components/select/pk-option-group.styles.ts","../../src/components/select/pk-option-group.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const pkOptionGroupStyles = css`\n @layer pk-component {\n :host {\n display: block;\n }\n\n /* Hard hex fallbacks: when groups portal outside pk-select, size-token\n * vars / theme tokens may be absent and invalid color inherits option black.\n * Weight/color match v1 ComboboxLabel / SelectLabel (text-slate-700, no font-medium). */\n .label {\n padding-block-start: var(--pk-select-group-label-padding-block-start, 8px);\n padding-block-end: var(--pk-select-group-label-padding-block-end, 2px);\n padding-inline: var(--pk-select-item-padding-inline, 10px);\n color: var(--pk-select-group-label-color, var(--pk-color-slate-700, rgba(96, 125, 159, 0.7)));\n font-family: var(--pk-font-family);\n /* Default matches v1 ComboboxLabel/SelectLabel text-xs (12px). */\n font-size: var(--pk-select-group-label-font-size, 12px);\n font-weight: 400;\n line-height: 1.3;\n /* Light-DOM ancestors (e.g. Formie empty dropzone text-center) must not center labels. */\n text-align: left;\n user-select: none;\n pointer-events: none;\n }\n\n :host([hidden]),\n :host([data-pk-filter-empty]) {\n display: none !important;\n }\n }\n`;\n","import { html } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\n\nimport { PkElement } from '../../base/pk-element.js';\nimport { uniqueId } from '../../a11y/focus.js';\nimport { pkOptionGroupStyles } from './pk-option-group.styles.js';\n\n/**\n * Visual option group for `pk-select` — listbox grouping pattern.\n *\n * @slot - `pk-option` items in this group\n *\n * @csspart label - Group label\n */\n@customElement('pk-option-group')\nexport class PkOptionGroup extends PkElement {\n static override styles = pkOptionGroupStyles;\n\n @property({ reflect: true })\n label = '';\n\n @property({ type: Boolean, reflect: true })\n hidden = false;\n\n private readonly labelId = uniqueId('pk-option-group-label');\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.setAttribute('role', 'group');\n this.setAttribute('aria-labelledby', this.labelId);\n }\n\n override render() {\n return html`\n <div part=\"label\" class=\"label\" id=${this.labelId}>${this.label}</div>\n <div role=\"presentation\">\n <slot></slot>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'pk-option-group': PkOptionGroup;\n }\n}\n"],"mappings":";;;;;AAEA,IAAa,sBAAsB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACa/B,IAAA,gBAAA,MAAM,sBAAsB,UAAU;;;eAIjC;gBAGC;iBAEkB,SAAS,wBAAwB;;;gBARnC;;CAUzB,oBAAmC;AAC/B,QAAM,mBAAmB;AACzB,OAAK,aAAa,QAAQ,QAAQ;AAClC,OAAK,aAAa,mBAAmB,KAAK,QAAQ;;CAGtD,SAAkB;AACd,SAAO,IAAI;iDAC8B,KAAK,QAAQ,GAAG,KAAK,MAAM;;;;;;;YAhBvE,SAAS,EAAE,SAAS,MAAM,CAAC,CAAA,EAAA,cAAA,WAAA,SAAA,KAAA,EAAA;YAG3B,SAAS;CAAE,MAAM;CAAS,SAAS;CAAM,CAAC,CAAA,EAAA,cAAA,WAAA,UAAA,KAAA,EAAA;4BAP9C,cAAc,kBAAkB,CAAA,EAAA,cAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pk-popover-CVvwXMld.js","names":[],"sources":["../../src/components/popover/pk-popover.styles.ts","../../src/components/popover/pk-popover.ts"],"sourcesContent":["import { css } from 'lit';\n\nimport { buttonGroupCornerRoleStyles } from '../button-group/button-group-item.styles.js';\nimport { popupContentAnimationStyles } from '../../styles/popup-content-animation.styles.js';\n\nexport const pkPopoverStyles = [\n buttonGroupCornerRoleStyles(),\n popupContentAnimationStyles,\n css`\n @layer pk-component {\n :host {\n /* Flex column parents stretch cross-axis size — pin to content.\n (inline-block + align-self; same class of fix as dialog / dropdown.) */\n display: inline-block;\n max-width: 100%;\n align-self: flex-start;\n flex: none;\n vertical-align: middle;\n }\n\n :host([data-pk-group-orientation]) {\n display: inline-flex;\n vertical-align: middle;\n flex: 0 0 auto;\n align-self: auto;\n }\n\n :host([data-pk-group-orientation]) ::slotted([slot='trigger']) {\n --pk-bg-start-start-radius: inherit;\n --pk-bg-start-end-radius: inherit;\n --pk-bg-end-start-radius: inherit;\n --pk-bg-end-end-radius: inherit;\n }\n\n :host([data-pk-group-orientation='horizontal'][data-pk-group-join]) {\n margin-inline-start: var(--pk-bg-horizontal-indent, 0);\n }\n\n :host([data-pk-group-orientation='vertical'][data-pk-group-join]) {\n margin-block-start: var(--pk-bg-vertical-indent, 0);\n }\n\n :host([data-pk-group-orientation='horizontal'][data-pk-group-join]:has([slot='trigger'][variant='outline'], [slot='trigger'][variant='dashed'])) {\n margin-inline-start: var(--pk-bg-horizontal-indent-outlined, 0);\n }\n\n :host([data-pk-group-orientation='vertical'][data-pk-group-join]:has([slot='trigger'][variant='outline'], [slot='trigger'][variant='dashed'])) {\n margin-block-start: var(--pk-bg-vertical-indent-outlined, 0);\n }\n\n /* Match pk-popup's arrow fill to the panel surface when with-arrow is on. */\n :host([with-arrow]) {\n --pk-popup-arrow-color: var(--pk-color-white);\n --pk-popup-arrow-size: 8px;\n }\n\n .panel {\n box-sizing: border-box;\n width: 18rem;\n padding: 1rem;\n border-radius: var(--pk-radius-md);\n background: var(--pk-color-white);\n box-shadow: var(--pk-shadow-popover);\n /* Craft CP body text (~gray-700), not gray-900. */\n color: var(--pk-color-gray-700);\n }\n\n /* Flush panels for command/menu chrome that owns its own inset (variable picker, etc.).\n Match kit v1 PopoverContent min-w 260px / max-w 360px: without min-width,\n width max-content shrinks to short labels and looks narrower than the old picker. */\n :host([flush]) .panel {\n width: max-content;\n min-width: var(--pk-popover-flush-min-width, 16.25rem);\n max-width: min(var(--pk-popover-flush-max-width, 22.5rem), 100vw - 1rem);\n padding: 0;\n }\n\n .panel[hidden] {\n display: none !important;\n }\n }\n `,\n];\n","import { html, nothing } from 'lit';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport type { PropertyValues } from 'lit';\n\nimport { isTopDismissible, registerDismissible, unregisterDismissible } from '../../a11y/dismissible-stack.js';\nimport { uniqueId } from '../../a11y/focus.js';\nimport { PkElement } from '../../base/pk-element.js';\nimport { resolveElementById } from '../../internal/resolve-element-by-id.js';\nimport {\n PkAfterHideEvent,\n PkAfterShowEvent,\n PkHideEvent,\n PkShowEvent,\n type PkOverlaySource,\n} from '../../events/overlay-lifecycle.js';\n// Keep the internal element registered when production builds erase type-only imports.\nimport '../popup/pk-popup.js';\nimport type { PkPopup, PkPopupPlacement } from '../popup/pk-popup.js';\nimport {\n syncPopupPlacementAnimation,\n waitForPopupReposition,\n} from '../../utils/popup-placement-animation.js';\nimport { isPointerInsideOverlay } from '../../utils/popup-pointer.js';\nimport { pkPopoverStyles } from './pk-popover.styles.js';\n\n/**\n * Popover — pattern: trigger toggles a floating panel.\n *\n * @slot trigger - Popover trigger\n * @slot - Popover content\n *\n * @csspart panel - Floating content panel\n *\n * @attr with-arrow - Show a pointing arrow toward the trigger (default: off)\n */\n@customElement('pk-popover')\nexport class PkPopover extends PkElement {\n static override styles = pkPopoverStyles;\n\n @property({ type: Boolean, reflect: true })\n open = false;\n\n @property({ reflect: true })\n placement: PkPopupPlacement = 'bottom';\n\n @property({ attribute: 'side-offset', type: Number })\n sideOffset = 4;\n\n /**\n * Drop default panel padding/fixed width so slotted chrome (command lists, etc.)\n * can control its own inset. Consumer outer `p-0` alone cannot reach `.panel`.\n */\n @property({ type: Boolean, reflect: true })\n flush = false;\n\n /**\n * Show a floating-ui arrow on the panel (off by default).\n * Named like other optional chrome (`with-clear`, `with-caret`) — tooltip always\n * paints its own arrow and has no toggle.\n */\n @property({ attribute: 'with-arrow', type: Boolean, reflect: true })\n withArrow = false;\n\n /** Anchor element id — alternative to the trigger slot. */\n @property({ reflect: true })\n for = '';\n\n /**\n * Live element anchor — use when the target lives in another shadow tree\n * (e.g. TipTap chips). Preferred over `for` / trigger slot when set.\n * Stays in the consumer tree so modal `showModal()` inert does not apply\n * (unlike portaling the panel to a root outside the dialog).\n */\n @property({ attribute: false })\n anchor: Element | null = null;\n\n @query('pk-popup')\n private popupElement!: PkPopup;\n\n private get panelElement(): HTMLDivElement | null {\n return this.popupElement?.getContentElement() as HTMLDivElement | null ?? null;\n }\n\n @state()\n private triggerElement: HTMLElement | null = null;\n\n /** True while the shared popup-content exit animation is running. */\n @state()\n private closing = false;\n\n /** Gates `data-open` so enter motion starts after Floating UI places the panel. */\n @state()\n private panelAnimated = false;\n\n private readonly triggerId = uniqueId('pk-popover-trigger');\n private dismissRegistered = false;\n /** Guard re-entry while openPopover/closePopover mutate `open`. */\n private syncingOpenSideEffects = false;\n /** Coalesce overlapping close calls (updated + light-dismiss) onto one exit. */\n private exitAnimationPromise: Promise<void> | null = null;\n\n override disconnectedCallback(): void {\n // Skip exit motion on teardown — demote immediately.\n void this.closePopover('api', true);\n super.disconnectedCallback();\n }\n\n /**\n * When controlled/toggle `open` flips false, arm `closing` in the same update so the\n * panel is not `hidden` for a frame before the exit animation starts.\n */\n override willUpdate(changed: PropertyValues): void {\n if (\n changed.has('open')\n && this.open === false\n && changed.get('open') === true\n && !this.syncingOpenSideEffects\n && !this.closing\n ) {\n this.closing = true;\n this.panelAnimated = false;\n }\n }\n\n /**\n * Controlled `open` (e.g. React) must arm/disarm light-dismiss the same way as\n * trigger toggles. Without this, programmatic open shows the panel but click-away\n * never fires.\n */\n override async updated(changed: PropertyValues): Promise<void> {\n super.updated(changed);\n\n if (!changed.has('open') || this.syncingOpenSideEffects) {\n return;\n }\n\n const previousOpen = changed.get('open');\n\n if (previousOpen === this.open) {\n return;\n }\n\n // Initial connect with open=false — nothing to tear down.\n if (previousOpen === undefined && this.open === false) {\n return;\n }\n\n if (this.open) {\n await this.openPopover();\n } else {\n await this.closePopover('api');\n }\n }\n\n private onTriggerSlotChange(event: Event): void {\n const slot = event.target as HTMLSlotElement;\n const [trigger] = slot.assignedElements({ flatten: true }) as HTMLElement[];\n\n this.unbindTrigger(this.triggerElement);\n this.triggerElement = trigger ?? null;\n this.bindTrigger(this.triggerElement);\n }\n\n private bindTrigger(trigger: HTMLElement | null): void {\n if (!trigger) {\n return;\n }\n\n if (!trigger.id) {\n trigger.id = this.triggerId;\n }\n\n trigger.setAttribute('aria-haspopup', 'dialog');\n trigger.addEventListener('click', this.handleToggleClick);\n this.syncExpanded();\n }\n\n private unbindTrigger(trigger: HTMLElement | null): void {\n trigger?.removeEventListener('click', this.handleToggleClick);\n }\n\n private handleToggleClick = (event: Event): void => {\n event.preventDefault();\n event.stopPropagation();\n\n if (this.closing) {\n return;\n }\n\n // Flip `open` only — side effects run from `updated()` (same as dropdown-menu).\n this.open = !this.open;\n };\n\n private async openPopover(): Promise<void> {\n if (!this.getAnchor()) {\n return;\n }\n\n // Finish any in-flight exit before arming a new open.\n if (this.exitAnimationPromise) {\n await this.exitAnimationPromise;\n }\n\n // Already armed from a prior controlled/toggle open.\n if (this.dismissRegistered && this.open) {\n if (this.panelElement) {\n this.panelElement.hidden = false;\n }\n this.syncExpanded();\n return;\n }\n\n if (!this.dispatchEvent(new PkShowEvent())) {\n this.syncingOpenSideEffects = true;\n this.open = false;\n this.syncingOpenSideEffects = false;\n return;\n }\n\n this.syncingOpenSideEffects = true;\n this.open = true;\n this.syncingOpenSideEffects = false;\n this.closing = false;\n this.panelAnimated = false;\n\n if (this.panelElement) {\n this.panelElement.hidden = false;\n // Seed side before first paint so enter keyframes pick a direction.\n syncPopupPlacementAnimation(this.panelElement, this.placement);\n }\n\n this.syncExpanded();\n this.registerDismissHandlers();\n\n await this.updateComplete;\n const placement = await waitForPopupReposition(this.popupElement, this.placement);\n\n if (this.panelElement) {\n syncPopupPlacementAnimation(this.panelElement, placement);\n }\n\n // Flip data-open after placement so the shared enter animation can run.\n this.panelAnimated = true;\n\n this.dispatchEvent(new PkAfterShowEvent());\n this.dispatchEvent(new CustomEvent('pk-open-change', {\n detail: { open: true },\n bubbles: true,\n composed: true,\n }));\n }\n\n /**\n * @param immediate Skip exit animation (disconnect / forced teardown).\n */\n async closePopover(source: PkOverlaySource = 'unknown', immediate = false): Promise<void> {\n if (this.exitAnimationPromise) {\n return this.exitAnimationPromise;\n }\n\n if (!this.dismissRegistered && !this.closing && !this.open) {\n return;\n }\n\n const hideEvent = new PkHideEvent(source);\n\n if (!this.dispatchEvent(hideEvent)) {\n // Controlled close was cancelled — restore open and cancel exit arming.\n this.syncingOpenSideEffects = true;\n this.open = true;\n this.syncingOpenSideEffects = false;\n this.closing = false;\n this.panelAnimated = true;\n return;\n }\n\n this.unregisterDismissHandlers();\n this.closing = true;\n this.panelAnimated = false;\n\n if (this.open) {\n this.syncingOpenSideEffects = true;\n this.open = false;\n this.syncingOpenSideEffects = false;\n }\n\n const finishClose = async (): Promise<void> => {\n if (!immediate) {\n await this.updateComplete;\n await this.waitForExitAnimation();\n }\n\n this.closing = false;\n this.panelAnimated = false;\n\n if (this.panelElement) {\n this.panelElement.hidden = true;\n this.panelElement.removeAttribute('data-side');\n }\n\n this.syncExpanded();\n\n this.dispatchEvent(new PkAfterHideEvent());\n this.dispatchEvent(new CustomEvent('pk-open-change', {\n detail: { open: false },\n bubbles: true,\n composed: true,\n }));\n };\n\n this.exitAnimationPromise = finishClose().finally(() => {\n this.exitAnimationPromise = null;\n });\n\n return this.exitAnimationPromise;\n }\n\n private waitForExitAnimation(): Promise<void> {\n const panel = this.panelElement;\n\n if (!panel) {\n return Promise.resolve();\n }\n\n return new Promise((resolve) => {\n let settled = false;\n\n const finish = (): void => {\n if (settled) {\n return;\n }\n\n settled = true;\n panel.removeEventListener('animationend', onAnimationEnd);\n window.clearTimeout(fallback);\n panel.classList.remove('closing');\n resolve();\n };\n\n const onAnimationEnd = (event: AnimationEvent): void => {\n if (event.target === panel && event.animationName.startsWith('pk-popup-content-out')) {\n finish();\n }\n };\n\n panel.classList.add('closing');\n panel.addEventListener('animationend', onAnimationEnd);\n const fallback = window.setTimeout(finish, 150);\n });\n }\n\n private getAnchor(): Element | string | null {\n if (this.anchor) {\n return this.anchor;\n }\n\n if (this.for) {\n return resolveElementById(this, this.for);\n }\n\n if (this.triggerElement) {\n return this.triggerElement;\n }\n\n return null;\n }\n\n private registerDismissHandlers(): void {\n if (this.dismissRegistered) {\n return;\n }\n\n registerDismissible(this);\n this.dismissRegistered = true;\n document.addEventListener('pointerdown', this.onDocumentPointerDown, true);\n document.addEventListener('keydown', this.onDocumentKeyDown, true);\n }\n\n private unregisterDismissHandlers(): void {\n if (this.dismissRegistered) {\n unregisterDismissible(this);\n this.dismissRegistered = false;\n }\n\n document.removeEventListener('pointerdown', this.onDocumentPointerDown, true);\n document.removeEventListener('keydown', this.onDocumentKeyDown, true);\n }\n\n private onDocumentPointerDown = (event: PointerEvent): void => {\n if (this.isPointerInside(event) || this.closing) {\n return;\n }\n\n void this.closePopover('light-dismiss');\n };\n\n private isPointerInside(event: PointerEvent): boolean {\n return isPointerInsideOverlay(event, {\n host: this,\n anchor: this.getAnchorElement(),\n panel: this.panelElement,\n });\n };\n\n private onDocumentKeyDown = (event: KeyboardEvent): void => {\n if (event.key !== 'Escape' || !isTopDismissible(this) || this.closing) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n void this.closePopover('escape');\n };\n\n private getAnchorElement(): HTMLElement | null {\n if (this.anchor instanceof HTMLElement) {\n return this.anchor;\n }\n\n if (this.triggerElement) {\n return this.triggerElement;\n }\n\n if (this.for) {\n return resolveElementById(this, this.for);\n }\n\n return null;\n }\n\n private syncExpanded(): void {\n this.triggerElement?.setAttribute('aria-expanded', this.open ? 'true' : 'false');\n }\n\n override render() {\n const anchor = this.getAnchor();\n\n return html`\n <slot name=\"trigger\" @slotchange=${this.onTriggerSlotChange}></slot>\n <pk-popup\n .active=${this.open || this.closing}\n .anchor=${anchor ?? ''}\n .placement=${this.placement}\n .distance=${this.sideOffset}\n .arrow=${this.withArrow}\n flip\n shift\n >\n <div\n part=\"panel\"\n class=${classMap({\n panel: true,\n 'pk-popup-content': true,\n closing: this.closing,\n })}\n ?hidden=${!this.open && !this.closing}\n data-open=${this.panelAnimated && !this.closing ? '' : nothing}\n tabindex=${this.open ? '-1' : nothing}\n >\n <slot></slot>\n </div>\n </pk-popup>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'pk-popover': PkPopover;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"pk-popover-G3ojheBD.js","names":[],"sources":["../../src/components/popover/pk-popover.styles.ts","../../src/components/popover/pk-popover.ts"],"sourcesContent":["import { css } from 'lit';\n\nimport { buttonGroupCornerRoleStyles } from '../button-group/button-group-item.styles.js';\nimport { popupContentAnimationStyles } from '../../styles/popup-content-animation.styles.js';\n\nexport const pkPopoverStyles = [\n buttonGroupCornerRoleStyles(),\n popupContentAnimationStyles,\n css`\n @layer pk-component {\n :host {\n /* Flex column parents stretch cross-axis size — pin to content.\n (inline-block + align-self; same class of fix as dialog / dropdown.) */\n display: inline-block;\n max-width: 100%;\n align-self: flex-start;\n flex: none;\n vertical-align: middle;\n }\n\n :host([data-pk-group-orientation]) {\n display: inline-flex;\n vertical-align: middle;\n flex: 0 0 auto;\n align-self: auto;\n }\n\n :host([data-pk-group-orientation]) ::slotted([slot='trigger']) {\n --pk-bg-start-start-radius: inherit;\n --pk-bg-start-end-radius: inherit;\n --pk-bg-end-start-radius: inherit;\n --pk-bg-end-end-radius: inherit;\n }\n\n :host([data-pk-group-orientation='horizontal'][data-pk-group-join]) {\n margin-inline-start: var(--pk-bg-horizontal-indent, 0);\n }\n\n :host([data-pk-group-orientation='vertical'][data-pk-group-join]) {\n margin-block-start: var(--pk-bg-vertical-indent, 0);\n }\n\n :host([data-pk-group-orientation='horizontal'][data-pk-group-join]:has([slot='trigger'][variant='outline'], [slot='trigger'][variant='dashed'])) {\n margin-inline-start: var(--pk-bg-horizontal-indent-outlined, 0);\n }\n\n :host([data-pk-group-orientation='vertical'][data-pk-group-join]:has([slot='trigger'][variant='outline'], [slot='trigger'][variant='dashed'])) {\n margin-block-start: var(--pk-bg-vertical-indent-outlined, 0);\n }\n\n /* Match pk-popup's arrow fill to the panel surface when with-arrow is on. */\n :host([with-arrow]) {\n --pk-popup-arrow-color: var(--pk-color-white);\n --pk-popup-arrow-size: 8px;\n }\n\n .panel {\n box-sizing: border-box;\n width: 18rem;\n padding: 1rem;\n border-radius: var(--pk-radius-md);\n background: var(--pk-color-white);\n box-shadow: var(--pk-shadow-popover);\n /* Craft CP body text (~gray-700), not gray-900. */\n color: var(--pk-color-gray-700);\n }\n\n /* Flush panels for command/menu chrome that owns its own inset (variable picker, etc.).\n Match kit v1 PopoverContent min-w 260px / max-w 360px: without min-width,\n width max-content shrinks to short labels and looks narrower than the old picker. */\n :host([flush]) .panel {\n width: max-content;\n min-width: var(--pk-popover-flush-min-width, 16.25rem);\n max-width: min(var(--pk-popover-flush-max-width, 22.5rem), 100vw - 1rem);\n padding: 0;\n }\n\n .panel[hidden] {\n display: none !important;\n }\n }\n `,\n];\n","import { html, nothing } from 'lit';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport type { PropertyValues } from 'lit';\n\nimport { isTopDismissible, registerDismissible, unregisterDismissible } from '../../a11y/dismissible-stack.js';\nimport { uniqueId } from '../../a11y/focus.js';\nimport { PkElement } from '../../base/pk-element.js';\nimport { resolveElementById } from '../../internal/resolve-element-by-id.js';\nimport {\n PkAfterHideEvent,\n PkAfterShowEvent,\n PkHideEvent,\n PkShowEvent,\n type PkOverlaySource,\n} from '../../events/overlay-lifecycle.js';\n// Keep the internal element registered when production builds erase type-only imports.\nimport '../popup/pk-popup.js';\nimport type { PkPopup, PkPopupPlacement } from '../popup/pk-popup.js';\nimport {\n syncPopupPlacementAnimation,\n waitForPopupReposition,\n} from '../../utils/popup-placement-animation.js';\nimport { isPointerInsideOverlay } from '../../utils/popup-pointer.js';\nimport { pkPopoverStyles } from './pk-popover.styles.js';\n\n/**\n * Popover — pattern: trigger toggles a floating panel.\n *\n * @slot trigger - Popover trigger\n * @slot - Popover content\n *\n * @csspart panel - Floating content panel\n *\n * @attr with-arrow - Show a pointing arrow toward the trigger (default: off)\n */\n@customElement('pk-popover')\nexport class PkPopover extends PkElement {\n static override styles = pkPopoverStyles;\n\n @property({ type: Boolean, reflect: true })\n open = false;\n\n @property({ reflect: true })\n placement: PkPopupPlacement = 'bottom';\n\n @property({ attribute: 'side-offset', type: Number })\n sideOffset = 4;\n\n /**\n * Drop default panel padding/fixed width so slotted chrome (command lists, etc.)\n * can control its own inset. Consumer outer `p-0` alone cannot reach `.panel`.\n */\n @property({ type: Boolean, reflect: true })\n flush = false;\n\n /**\n * Show a floating-ui arrow on the panel (off by default).\n * Named like other optional chrome (`with-clear`, `with-caret`) — tooltip always\n * paints its own arrow and has no toggle.\n */\n @property({ attribute: 'with-arrow', type: Boolean, reflect: true })\n withArrow = false;\n\n /** Anchor element id — alternative to the trigger slot. */\n @property({ reflect: true })\n for = '';\n\n /**\n * Live element anchor — use when the target lives in another shadow tree\n * (e.g. TipTap chips). Preferred over `for` / trigger slot when set.\n * Stays in the consumer tree so modal `showModal()` inert does not apply\n * (unlike portaling the panel to a root outside the dialog).\n */\n @property({ attribute: false })\n anchor: Element | null = null;\n\n @query('pk-popup')\n private popupElement!: PkPopup;\n\n private get panelElement(): HTMLDivElement | null {\n return this.popupElement?.getContentElement() as HTMLDivElement | null ?? null;\n }\n\n @state()\n private triggerElement: HTMLElement | null = null;\n\n /** True while the shared popup-content exit animation is running. */\n @state()\n private closing = false;\n\n /** Gates `data-open` so enter motion starts after Floating UI places the panel. */\n @state()\n private panelAnimated = false;\n\n private readonly triggerId = uniqueId('pk-popover-trigger');\n private dismissRegistered = false;\n /** Guard re-entry while openPopover/closePopover mutate `open`. */\n private syncingOpenSideEffects = false;\n /** Coalesce overlapping close calls (updated + light-dismiss) onto one exit. */\n private exitAnimationPromise: Promise<void> | null = null;\n\n override disconnectedCallback(): void {\n // Skip exit motion on teardown — demote immediately.\n void this.closePopover('api', true);\n super.disconnectedCallback();\n }\n\n /**\n * When controlled/toggle `open` flips false, arm `closing` in the same update so the\n * panel is not `hidden` for a frame before the exit animation starts.\n */\n override willUpdate(changed: PropertyValues): void {\n if (\n changed.has('open')\n && this.open === false\n && changed.get('open') === true\n && !this.syncingOpenSideEffects\n && !this.closing\n ) {\n this.closing = true;\n this.panelAnimated = false;\n }\n }\n\n /**\n * Controlled `open` (e.g. React) must arm/disarm light-dismiss the same way as\n * trigger toggles. Without this, programmatic open shows the panel but click-away\n * never fires.\n */\n override async updated(changed: PropertyValues): Promise<void> {\n super.updated(changed);\n\n if (!changed.has('open') || this.syncingOpenSideEffects) {\n return;\n }\n\n const previousOpen = changed.get('open');\n\n if (previousOpen === this.open) {\n return;\n }\n\n // Initial connect with open=false — nothing to tear down.\n if (previousOpen === undefined && this.open === false) {\n return;\n }\n\n if (this.open) {\n await this.openPopover();\n } else {\n await this.closePopover('api');\n }\n }\n\n private onTriggerSlotChange(event: Event): void {\n const slot = event.target as HTMLSlotElement;\n const [trigger] = slot.assignedElements({ flatten: true }) as HTMLElement[];\n\n this.unbindTrigger(this.triggerElement);\n this.triggerElement = trigger ?? null;\n this.bindTrigger(this.triggerElement);\n }\n\n private bindTrigger(trigger: HTMLElement | null): void {\n if (!trigger) {\n return;\n }\n\n if (!trigger.id) {\n trigger.id = this.triggerId;\n }\n\n trigger.setAttribute('aria-haspopup', 'dialog');\n trigger.addEventListener('click', this.handleToggleClick);\n this.syncExpanded();\n }\n\n private unbindTrigger(trigger: HTMLElement | null): void {\n trigger?.removeEventListener('click', this.handleToggleClick);\n }\n\n private handleToggleClick = (event: Event): void => {\n event.preventDefault();\n event.stopPropagation();\n\n if (this.closing) {\n return;\n }\n\n // Flip `open` only — side effects run from `updated()` (same as dropdown-menu).\n this.open = !this.open;\n };\n\n private async openPopover(): Promise<void> {\n if (!this.getAnchor()) {\n return;\n }\n\n // Finish any in-flight exit before arming a new open.\n if (this.exitAnimationPromise) {\n await this.exitAnimationPromise;\n }\n\n // Already armed from a prior controlled/toggle open.\n if (this.dismissRegistered && this.open) {\n if (this.panelElement) {\n this.panelElement.hidden = false;\n }\n this.syncExpanded();\n return;\n }\n\n if (!this.dispatchEvent(new PkShowEvent())) {\n this.syncingOpenSideEffects = true;\n this.open = false;\n this.syncingOpenSideEffects = false;\n return;\n }\n\n this.syncingOpenSideEffects = true;\n this.open = true;\n this.syncingOpenSideEffects = false;\n this.closing = false;\n this.panelAnimated = false;\n\n if (this.panelElement) {\n this.panelElement.hidden = false;\n // Seed side before first paint so enter keyframes pick a direction.\n syncPopupPlacementAnimation(this.panelElement, this.placement);\n }\n\n this.syncExpanded();\n this.registerDismissHandlers();\n\n await this.updateComplete;\n const placement = await waitForPopupReposition(this.popupElement, this.placement);\n\n if (this.panelElement) {\n syncPopupPlacementAnimation(this.panelElement, placement);\n }\n\n // Flip data-open after placement so the shared enter animation can run.\n this.panelAnimated = true;\n\n this.dispatchEvent(new PkAfterShowEvent());\n this.dispatchEvent(new CustomEvent('pk-open-change', {\n detail: { open: true },\n bubbles: true,\n composed: true,\n }));\n }\n\n /**\n * @param immediate Skip exit animation (disconnect / forced teardown).\n */\n async closePopover(source: PkOverlaySource = 'unknown', immediate = false): Promise<void> {\n if (this.exitAnimationPromise) {\n return this.exitAnimationPromise;\n }\n\n if (!this.dismissRegistered && !this.closing && !this.open) {\n return;\n }\n\n const hideEvent = new PkHideEvent(source);\n\n if (!this.dispatchEvent(hideEvent)) {\n // Controlled close was cancelled — restore open and cancel exit arming.\n this.syncingOpenSideEffects = true;\n this.open = true;\n this.syncingOpenSideEffects = false;\n this.closing = false;\n this.panelAnimated = true;\n return;\n }\n\n this.unregisterDismissHandlers();\n this.closing = true;\n this.panelAnimated = false;\n\n if (this.open) {\n this.syncingOpenSideEffects = true;\n this.open = false;\n this.syncingOpenSideEffects = false;\n }\n\n const finishClose = async (): Promise<void> => {\n if (!immediate) {\n await this.updateComplete;\n await this.waitForExitAnimation();\n }\n\n this.closing = false;\n this.panelAnimated = false;\n\n if (this.panelElement) {\n this.panelElement.hidden = true;\n this.panelElement.removeAttribute('data-side');\n }\n\n this.syncExpanded();\n\n this.dispatchEvent(new PkAfterHideEvent());\n this.dispatchEvent(new CustomEvent('pk-open-change', {\n detail: { open: false },\n bubbles: true,\n composed: true,\n }));\n };\n\n this.exitAnimationPromise = finishClose().finally(() => {\n this.exitAnimationPromise = null;\n });\n\n return this.exitAnimationPromise;\n }\n\n private waitForExitAnimation(): Promise<void> {\n const panel = this.panelElement;\n\n if (!panel) {\n return Promise.resolve();\n }\n\n return new Promise((resolve) => {\n let settled = false;\n\n const finish = (): void => {\n if (settled) {\n return;\n }\n\n settled = true;\n panel.removeEventListener('animationend', onAnimationEnd);\n window.clearTimeout(fallback);\n panel.classList.remove('closing');\n resolve();\n };\n\n const onAnimationEnd = (event: AnimationEvent): void => {\n if (event.target === panel && event.animationName.startsWith('pk-popup-content-out')) {\n finish();\n }\n };\n\n panel.classList.add('closing');\n panel.addEventListener('animationend', onAnimationEnd);\n const fallback = window.setTimeout(finish, 150);\n });\n }\n\n private getAnchor(): Element | string | null {\n if (this.anchor) {\n return this.anchor;\n }\n\n if (this.for) {\n return resolveElementById(this, this.for);\n }\n\n if (this.triggerElement) {\n return this.triggerElement;\n }\n\n return null;\n }\n\n private registerDismissHandlers(): void {\n if (this.dismissRegistered) {\n return;\n }\n\n registerDismissible(this);\n this.dismissRegistered = true;\n document.addEventListener('pointerdown', this.onDocumentPointerDown, true);\n document.addEventListener('keydown', this.onDocumentKeyDown, true);\n }\n\n private unregisterDismissHandlers(): void {\n if (this.dismissRegistered) {\n unregisterDismissible(this);\n this.dismissRegistered = false;\n }\n\n document.removeEventListener('pointerdown', this.onDocumentPointerDown, true);\n document.removeEventListener('keydown', this.onDocumentKeyDown, true);\n }\n\n private onDocumentPointerDown = (event: PointerEvent): void => {\n if (this.isPointerInside(event) || this.closing) {\n return;\n }\n\n void this.closePopover('light-dismiss');\n };\n\n private isPointerInside(event: PointerEvent): boolean {\n return isPointerInsideOverlay(event, {\n host: this,\n anchor: this.getAnchorElement(),\n panel: this.panelElement,\n });\n };\n\n private onDocumentKeyDown = (event: KeyboardEvent): void => {\n if (event.key !== 'Escape' || !isTopDismissible(this) || this.closing) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n void this.closePopover('escape');\n };\n\n private getAnchorElement(): HTMLElement | null {\n if (this.anchor instanceof HTMLElement) {\n return this.anchor;\n }\n\n if (this.triggerElement) {\n return this.triggerElement;\n }\n\n if (this.for) {\n return resolveElementById(this, this.for);\n }\n\n return null;\n }\n\n private syncExpanded(): void {\n this.triggerElement?.setAttribute('aria-expanded', this.open ? 'true' : 'false');\n }\n\n override render() {\n const anchor = this.getAnchor();\n\n return html`\n <slot name=\"trigger\" @slotchange=${this.onTriggerSlotChange}></slot>\n <pk-popup\n .active=${this.open || this.closing}\n .anchor=${anchor ?? ''}\n .placement=${this.placement}\n .distance=${this.sideOffset}\n .arrow=${this.withArrow}\n flip\n shift\n >\n <div\n part=\"panel\"\n class=${classMap({\n panel: true,\n 'pk-popup-content': true,\n closing: this.closing,\n })}\n ?hidden=${!this.open && !this.closing}\n data-open=${this.panelAnimated && !this.closing ? '' : nothing}\n tabindex=${this.open ? '-1' : nothing}\n >\n <slot></slot>\n </div>\n </pk-popup>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'pk-popover': PkPopover;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pk-radio-
|
|
1
|
+
{"version":3,"file":"pk-radio-CDfhOW8L.js","names":[],"sources":["../../src/components/radio-group/pk-radio.styles.ts","../../src/components/radio-group/pk-radio.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const pkRadioStyles = css`\n @layer pk-component {\n :host {\n display: inline-flex;\n vertical-align: middle;\n font-family: var(--pk-font-family);\n font-size: var(--pk-font-size-base);\n line-height: var(--pk-line-height);\n }\n\n :host([disabled]) {\n cursor: not-allowed;\n opacity: 0.5;\n }\n\n .item {\n display: inline-flex;\n align-items: center;\n cursor: pointer;\n user-select: none;\n position: relative;\n margin: 0;\n }\n\n :host([disabled]) .item {\n cursor: not-allowed;\n }\n\n .item--with-label {\n gap: 0.5rem;\n }\n\n .control {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 1rem;\n height: 1rem;\n border: 1px solid var(--pk-color-slate-400);\n border-radius: 9999px;\n background: var(--pk-color-white);\n transition: border-color 0.12s ease, box-shadow 0.12s ease;\n }\n\n .item:focus-visible .control,\n :host([data-focus-visible]) .control {\n border-color: var(--pk-color-sky-600);\n box-shadow: 0 0 0 1px var(--pk-color-sky-600), 0 0 4px 0 hsl(from var(--pk-color-sky-600) h s l / 0.7);\n }\n\n :host([invalid]) .control {\n border-color: var(--pk-color-rose-600);\n }\n\n :host([invalid]:focus-visible) .control,\n :host([invalid][data-focus-visible]) .control {\n box-shadow: 0 0 0 1px var(--pk-color-rose-600), 0 0 4px 0 hsl(from var(--pk-color-rose-600) h s l / 0.7);\n }\n\n :host([checked]) .control {\n background: var(--pk-color-gray-50);\n color: #1f2933;\n }\n\n .indicator {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n color: currentcolor;\n }\n\n .indicator-dot {\n width: 0.5rem;\n height: 0.5rem;\n border-radius: 9999px;\n background: currentcolor;\n transition: opacity 0.12s ease, transform 0.12s ease;\n }\n\n :host(:not([checked])) .indicator-dot {\n opacity: 0;\n transform: scale(0);\n }\n\n .input {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n opacity: 0;\n appearance: none;\n }\n\n .label {\n line-height: var(--pk-line-height);\n /* Match checkbox / form-control labels (gray-700). */\n color: var(--pk-color-gray-700);\n }\n\n .label.is-empty {\n display: none;\n }\n }\n`;\n","import { html, nothing } from 'lit';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport type { PropertyValues } from 'lit';\n\nimport { PkElement } from '../../base/pk-element.js';\nimport { pkRadioStyles } from './pk-radio.styles.js';\n\n/**\n * Radio button — use inside `pk-radio-group`.\n *\n * @slot - Visible label text\n *\n * @csspart base - Root label element\n * @csspart input - Native radio input\n * @csspart control - Visual radio circle\n * @csspart indicator - Indicator container\n */\n@customElement('pk-radio')\nexport class PkRadio extends PkElement {\n static override styles = pkRadioStyles;\n\n @property()\n value = '';\n\n @property({ type: Boolean, reflect: true })\n checked = false;\n\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n @property({ type: Boolean, reflect: true })\n invalid = false;\n\n @property({ type: Boolean, reflect: true })\n required = false;\n\n @property({ type: Number })\n tabIndex = -1;\n\n @property({ attribute: 'aria-label' })\n ariaLabel: string | null = null;\n\n /** Set by `pk-radio-group` when the group is disabled. */\n @property({ type: Boolean, attribute: false })\n forceDisabled = false;\n\n @query('.input')\n private input!: HTMLInputElement;\n\n @state()\n private hasDefaultSlotContent = false;\n\n override updated(changed: PropertyValues): void {\n if (this.input && changed.has('checked')) {\n this.input.checked = this.checked;\n }\n\n if (this.input && changed.has('tabIndex')) {\n this.input.tabIndex = this.tabIndex;\n }\n }\n\n focusControl(options?: FocusOptions): void {\n this.input.focus(options);\n }\n\n private defaultSlotChanged(event: Event): void {\n const slot = event.target as HTMLSlotElement;\n this.hasDefaultSlotContent = slot.assignedNodes({ flatten: true }).some((node) => {\n if (node.nodeType === Node.TEXT_NODE) {\n return node.textContent?.trim();\n }\n\n return node.nodeType === Node.ELEMENT_NODE;\n });\n }\n\n private handleChange(event: Event): void {\n event.stopPropagation();\n const input = event.target as HTMLInputElement;\n\n if (this.disabled || this.forceDisabled || !input.checked) {\n return;\n }\n\n this.dispatchEvent(new CustomEvent('pk-radio-select', {\n detail: { value: this.value },\n bubbles: true,\n composed: true,\n }));\n }\n\n override render() {\n const isDisabled = this.disabled || this.forceDisabled;\n\n return html`\n <label\n part=\"base\"\n class=${classMap({\n item: true,\n 'pk-radio-group__item': true,\n 'item--with-label': this.hasDefaultSlotContent,\n })}\n data-state=${this.checked ? 'checked' : nothing}\n ?data-disabled=${isDisabled}\n aria-disabled=${isDisabled ? 'true' : nothing}\n >\n <span part=\"control\" class=\"control pk-radio-group__control\">\n <span part=\"indicator\" class=\"indicator pk-radio-group__indicator\">\n <span class=\"indicator-dot pk-radio-group__indicator-dot\"></span>\n </span>\n </span>\n <input\n part=\"input\"\n class=\"input\"\n type=\"radio\"\n .checked=${this.checked}\n ?disabled=${isDisabled}\n ?required=${this.required}\n value=${this.value}\n tabindex=${this.tabIndex}\n aria-label=${this.ariaLabel ?? nothing}\n aria-invalid=${this.invalid ? 'true' : nothing}\n aria-checked=${this.checked ? 'true' : 'false'}\n @change=${this.handleChange}\n />\n <span\n class=${classMap({\n label: true,\n 'is-empty': !this.hasDefaultSlotContent,\n })}\n >\n <slot @slotchange=${this.defaultSlotChanged}></slot>\n </span>\n </label>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'pk-radio': PkRadio;\n }\n}\n"],"mappings":";;;;;AAEA,IAAa,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACiBzB,IAAA,UAAA,MAAM,gBAAgB,UAAU;;;eAI3B;iBAGE;kBAGC;iBAGD;kBAGC;kBAGA;mBAGgB;uBAIX;+BAMgB;;;gBA/BP;;CAiCzB,QAAiB,SAA+B;AAC5C,MAAI,KAAK,SAAS,QAAQ,IAAI,UAAU,CACpC,MAAK,MAAM,UAAU,KAAK;AAG9B,MAAI,KAAK,SAAS,QAAQ,IAAI,WAAW,CACrC,MAAK,MAAM,WAAW,KAAK;;CAInC,aAAa,SAA8B;AACvC,OAAK,MAAM,MAAM,QAAQ;;CAG7B,mBAA2B,OAAoB;EAC3C,MAAM,OAAO,MAAM;AACnB,OAAK,wBAAwB,KAAK,cAAc,EAAE,SAAS,MAAM,CAAC,CAAC,MAAM,SAAS;AAC9E,OAAI,KAAK,aAAa,KAAK,UACvB,QAAO,KAAK,aAAa,MAAM;AAGnC,UAAO,KAAK,aAAa,KAAK;IAChC;;CAGN,aAAqB,OAAoB;AACrC,QAAM,iBAAiB;EACvB,MAAM,QAAQ,MAAM;AAEpB,MAAI,KAAK,YAAY,KAAK,iBAAiB,CAAC,MAAM,QAC9C;AAGJ,OAAK,cAAc,IAAI,YAAY,mBAAmB;GAClD,QAAQ,EAAE,OAAO,KAAK,OAAO;GAC7B,SAAS;GACT,UAAU;GACb,CAAC,CAAC;;CAGP,SAAkB;EACd,MAAM,aAAa,KAAK,YAAY,KAAK;AAEzC,SAAO,IAAI;;;wBAGK,SAAS;GACb,MAAM;GACN,wBAAwB;GACxB,oBAAoB,KAAK;GAC5B,CAAC,CAAC;6BACU,KAAK,UAAU,YAAY,QAAQ;iCAC/B,WAAW;gCACZ,aAAa,SAAS,QAAQ;;;;;;;;;;;+BAW/B,KAAK,QAAQ;gCACZ,WAAW;gCACX,KAAK,SAAS;4BAClB,KAAK,MAAM;+BACR,KAAK,SAAS;iCACZ,KAAK,aAAa,QAAQ;mCACxB,KAAK,UAAU,SAAS,QAAQ;mCAChC,KAAK,UAAU,SAAS,QAAQ;8BACrC,KAAK,aAAa;;;4BAGpB,SAAS;GACb,OAAO;GACP,YAAY,CAAC,KAAK;GACrB,CAAC,CAAC;;wCAEiB,KAAK,mBAAmB;;;;;;YA/G3D,UAAU,CAAA,EAAA,QAAA,WAAA,SAAA,KAAA,EAAA;YAGV,SAAS;CAAE,MAAM;CAAS,SAAS;CAAM,CAAC,CAAA,EAAA,QAAA,WAAA,WAAA,KAAA,EAAA;YAG1C,SAAS;CAAE,MAAM;CAAS,SAAS;CAAM,CAAC,CAAA,EAAA,QAAA,WAAA,YAAA,KAAA,EAAA;YAG1C,SAAS;CAAE,MAAM;CAAS,SAAS;CAAM,CAAC,CAAA,EAAA,QAAA,WAAA,WAAA,KAAA,EAAA;YAG1C,SAAS;CAAE,MAAM;CAAS,SAAS;CAAM,CAAC,CAAA,EAAA,QAAA,WAAA,YAAA,KAAA,EAAA;YAG1C,SAAS,EAAE,MAAM,QAAQ,CAAC,CAAA,EAAA,QAAA,WAAA,YAAA,KAAA,EAAA;YAG1B,SAAS,EAAE,WAAW,cAAc,CAAC,CAAA,EAAA,QAAA,WAAA,aAAA,KAAA,EAAA;YAIrC,SAAS;CAAE,MAAM;CAAS,WAAW;CAAO,CAAC,CAAA,EAAA,QAAA,WAAA,iBAAA,KAAA,EAAA;YAG7C,MAAM,SAAS,CAAA,EAAA,QAAA,WAAA,SAAA,KAAA,EAAA;YAGf,OAAO,CAAA,EAAA,QAAA,WAAA,yBAAA,KAAA,EAAA;sBAhCX,cAAc,WAAW,CAAA,EAAA,QAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pk-radio-group-B5rps9G4.js","names":[],"sources":["../../src/components/radio-group/pk-radio-group.styles.ts","../../src/components/radio-group/pk-radio-group.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const pkRadioGroupStyles = css`\n @layer pk-component {\n :host {\n display: block;\n font-family: var(--pk-font-family);\n font-size: var(--pk-font-size-base);\n line-height: var(--pk-line-height);\n }\n\n .group {\n display: grid;\n gap: 0.375rem;\n }\n\n .group--horizontal {\n grid-auto-flow: column;\n grid-auto-columns: max-content;\n align-items: center;\n }\n }\n`;\n","import { html, nothing } from 'lit';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport type { PropertyValues } from 'lit';\n\nimport { formControlStyles } from '../../base/form-control.styles.js';\nimport { PkFormAssociatedElement } from '../../base/pk-form-associated-element.js';\nimport { HasSlotController } from '../../internal/has-slot.js';\nimport { hasInstructionContent, readLegacyInstructions } from '../../internal/field-labels.js';\nimport { RequiredValidator } from '../../validators/index.js';\nimport type { PkRadio } from './pk-radio.js';\nimport { pkRadioGroupStyles } from './pk-radio-group.styles.js';\n\nexport type PkRadioGroupOrientation = 'horizontal' | 'vertical';\n\n/**\n * Radio group — pattern: light-DOM `pk-radio` children, shared value + validation.\n *\n * @slot label - Group label\n * @slot instructions - Instructions text\n * @slot hint - Alias for `instructions`\n * @slot - `pk-radio` items\n *\n * @csspart form-control - Form control wrapper\n * @csspart label - Label text\n * @csspart radios - Radio items container\n * @csspart instructions - Instructions text\n */\n@customElement('pk-radio-group')\nexport class PkRadioGroup extends PkFormAssociatedElement {\n static override shadowRootOptions: ShadowRootInit = {\n mode: 'open',\n delegatesFocus: true,\n };\n\n static override styles = [formControlStyles, pkRadioGroupStyles];\n\n static override get validators() {\n return [...super.validators, RequiredValidator()];\n }\n\n override assumeInteractionOn = ['change'];\n\n private readonly hasSlotController = new HasSlotController(this, 'instructions', 'hint', 'label');\n\n private _value: string | null = null;\n\n get value(): string {\n if (this.valueHasChanged) {\n return this._value ?? '';\n }\n\n return this._value ?? this.defaultValue ?? '';\n }\n\n set value(val: string | null) {\n this._value = val == null ? null : String(val);\n this.valueHasChanged = true;\n }\n\n /** Default value — reflected as the `value` attribute. */\n @property({ attribute: 'value', reflect: true })\n defaultValue = '';\n\n @property({ reflect: true })\n orientation: PkRadioGroupOrientation = 'vertical';\n\n @property({ type: Boolean, reflect: true })\n invalid = false;\n\n @property()\n label = '';\n\n @property()\n instructions = '';\n\n @property({ attribute: 'aria-label' })\n override ariaLabel: string | null = null;\n\n @query('slot:not([name])')\n private defaultSlot!: HTMLSlotElement;\n\n @state()\n private items: PkRadio[] = [];\n\n protected override syncFormValue(): void {\n this.setFormValue(this.value || null);\n }\n\n protected override resetToDefaultValue(): void {\n this._value = null;\n this.applySelection();\n }\n\n protected override restoreFormState(state: string | File | FormData | null): void {\n if (typeof state === 'string') {\n this.value = state;\n this.applySelection();\n }\n }\n\n protected override get validationTarget(): HTMLElement | undefined {\n return this.getAllRadios().find((item) => !item.disabled) ?? this.getAllRadios()[0];\n }\n\n override connectedCallback(): void {\n this.instructions = readLegacyInstructions(this, this.instructions);\n super.connectedCallback();\n this.addEventListener('keydown', this.handleKeyDown);\n this.addEventListener('click', this.handleRadioClick);\n }\n\n override disconnectedCallback(): void {\n this.removeEventListener('keydown', this.handleKeyDown);\n this.removeEventListener('click', this.handleRadioClick);\n super.disconnectedCallback();\n }\n\n override updated(changed: PropertyValues): void {\n if (changed.has('value') || changed.has('disabled') || changed.has('invalid') || changed.has('name')) {\n this.applySelection();\n }\n\n super.updated(changed);\n }\n\n override formResetCallback(): void {\n this._value = null;\n super.formResetCallback();\n this.applySelection();\n }\n\n override focus(options?: FocusOptions): void {\n if (this.disabled) {\n return;\n }\n\n const radios = this.getEnabledItems();\n const checked = radios.find((radio) => radio.checked);\n const target = checked ?? radios[0];\n target?.focusControl(options);\n }\n\n private getAllRadios(): PkRadio[] {\n return [...this.querySelectorAll('pk-radio')];\n }\n\n private syncItems = (): void => {\n this.items = this.getAllRadios();\n this.applySelection();\n };\n\n private getEnabledItems(): PkRadio[] {\n return this.items.filter((item) => !item.disabled && !this.disabled);\n }\n\n private applySelection(): void {\n const radios = this.getAllRadios();\n this.items = radios;\n\n const enabled = this.getEnabledItems();\n const checkedRadio = enabled.find((item) => item.value === this.value);\n\n for (const item of radios) {\n const checked = item.value === this.value;\n // React sets CE booleans as properties, while hand-written HTML uses attributes.\n // Preserve item-level disabled state from either source, but do not let a prior\n // group-level disabled pass permanently mark every child disabled.\n const itemDisabled = item.hasAttribute('disabled') || (item.disabled && !item.forceDisabled);\n item.checked = checked;\n item.disabled = this.disabled || itemDisabled;\n item.invalid = this.invalid;\n item.required = this.required;\n item.forceDisabled = this.disabled;\n }\n\n if (this.disabled) {\n for (const item of radios) {\n item.tabIndex = -1;\n }\n return;\n }\n\n if (checkedRadio) {\n for (const item of enabled) {\n item.tabIndex = item.checked ? 0 : -1;\n }\n } else if (enabled.length > 0) {\n enabled.forEach((item, index) => {\n item.tabIndex = index === 0 ? 0 : -1;\n });\n }\n\n for (const item of radios.filter((radio) => radio.disabled)) {\n item.tabIndex = -1;\n }\n }\n\n private handleRadioClick = (event: Event): void => {\n const clickedRadio = (event.target as HTMLElement).closest('pk-radio') as PkRadio | null;\n\n if (!clickedRadio || clickedRadio.disabled || clickedRadio.forceDisabled || this.disabled) {\n return;\n }\n\n const oldValue = this.value;\n this.value = clickedRadio.value;\n this.applySelection();\n\n if (this.value !== oldValue) {\n this.emitValueChange();\n }\n };\n\n private handleKeyDown = (event: KeyboardEvent): void => {\n if (!['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', ' ', 'Home', 'End'].includes(event.key) || this.disabled) {\n return;\n }\n\n const radios = this.getEnabledItems();\n\n if (radios.length === 0) {\n return;\n }\n\n event.preventDefault();\n\n const oldValue = this.value;\n const checkedRadio = radios.find((radio) => radio.checked) ?? radios[0]!;\n let index = radios.indexOf(checkedRadio);\n\n if (event.key === ' ') {\n // Space selects focused radio without moving\n } else if (event.key === 'Home') {\n index = 0;\n } else if (event.key === 'End') {\n index = radios.length - 1;\n } else {\n const increment = ['ArrowUp', 'ArrowLeft'].includes(event.key) ? -1 : 1;\n index += increment;\n\n if (index < 0) {\n index = radios.length - 1;\n }\n\n if (index >= radios.length) {\n index = 0;\n }\n }\n\n this.value = radios[index]!.value;\n this.applySelection();\n radios[index]!.focusControl();\n\n if (this.value !== oldValue) {\n this.emitValueChange();\n }\n };\n\n private emitValueChange(): void {\n this.dispatchEvent(new CustomEvent('pk-change', {\n detail: { value: this.value },\n bubbles: true,\n composed: true,\n }));\n\n this.dispatchEvent(new Event('input', { bubbles: true, composed: true }));\n this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));\n }\n\n override render() {\n const hasLabelSlot = this.hasSlotController.test('label');\n const hasInstructions = hasInstructionContent(\n (name, flag) => this.hasSlotController.test(name, flag),\n this.instructions,\n );\n const hasLabel = Boolean(this.label) || hasLabelSlot;\n\n return html`\n <div part=\"form-control\" class=\"form-control\">\n ${hasLabel\n ? html`\n <div part=\"label\" class=\"form-control__label\" id=\"label\">\n <slot name=\"label\">${this.label}</slot>\n </div>\n `\n : nothing}\n\n ${hasInstructions\n ? html`\n <div part=\"instructions\" class=\"form-control__instructions\" id=\"instructions\">\n <slot name=\"instructions\">${this.instructions}</slot>\n <slot name=\"hint\"></slot>\n </div>\n `\n : nothing}\n\n <div\n part=\"radios\"\n class=${classMap({\n group: true,\n 'pk-radio-group': true,\n 'group--horizontal': this.orientation === 'horizontal',\n 'pk-radio-group--horizontal': this.orientation === 'horizontal',\n })}\n role=\"radiogroup\"\n aria-labelledby=${hasLabel ? 'label' : nothing}\n aria-label=${!hasLabel ? (this.ariaLabel ?? nothing) : nothing}\n aria-describedby=${hasInstructions ? 'instructions' : nothing}\n aria-invalid=${this.invalid ? 'true' : nothing}\n aria-required=${this.required ? 'true' : nothing}\n >\n <slot @slotchange=${this.syncItems}></slot>\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'pk-radio-group': PkRadioGroup;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"pk-radio-group-BazmLDvl.js","names":[],"sources":["../../src/components/radio-group/pk-radio-group.styles.ts","../../src/components/radio-group/pk-radio-group.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const pkRadioGroupStyles = css`\n @layer pk-component {\n :host {\n display: block;\n font-family: var(--pk-font-family);\n font-size: var(--pk-font-size-base);\n line-height: var(--pk-line-height);\n }\n\n .group {\n display: grid;\n gap: 0.375rem;\n }\n\n .group--horizontal {\n grid-auto-flow: column;\n grid-auto-columns: max-content;\n align-items: center;\n }\n }\n`;\n","import { html, nothing } from 'lit';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport type { PropertyValues } from 'lit';\n\nimport { formControlStyles } from '../../base/form-control.styles.js';\nimport { PkFormAssociatedElement } from '../../base/pk-form-associated-element.js';\nimport { HasSlotController } from '../../internal/has-slot.js';\nimport { hasInstructionContent, readLegacyInstructions } from '../../internal/field-labels.js';\nimport { RequiredValidator } from '../../validators/index.js';\nimport type { PkRadio } from './pk-radio.js';\nimport { pkRadioGroupStyles } from './pk-radio-group.styles.js';\n\nexport type PkRadioGroupOrientation = 'horizontal' | 'vertical';\n\n/**\n * Radio group — pattern: light-DOM `pk-radio` children, shared value + validation.\n *\n * @slot label - Group label\n * @slot instructions - Instructions text\n * @slot hint - Alias for `instructions`\n * @slot - `pk-radio` items\n *\n * @csspart form-control - Form control wrapper\n * @csspart label - Label text\n * @csspart radios - Radio items container\n * @csspart instructions - Instructions text\n */\n@customElement('pk-radio-group')\nexport class PkRadioGroup extends PkFormAssociatedElement {\n static override shadowRootOptions: ShadowRootInit = {\n mode: 'open',\n delegatesFocus: true,\n };\n\n static override styles = [formControlStyles, pkRadioGroupStyles];\n\n static override get validators() {\n return [...super.validators, RequiredValidator()];\n }\n\n override assumeInteractionOn = ['change'];\n\n private readonly hasSlotController = new HasSlotController(this, 'instructions', 'hint', 'label');\n\n private _value: string | null = null;\n\n get value(): string {\n if (this.valueHasChanged) {\n return this._value ?? '';\n }\n\n return this._value ?? this.defaultValue ?? '';\n }\n\n set value(val: string | null) {\n this._value = val == null ? null : String(val);\n this.valueHasChanged = true;\n }\n\n /** Default value — reflected as the `value` attribute. */\n @property({ attribute: 'value', reflect: true })\n defaultValue = '';\n\n @property({ reflect: true })\n orientation: PkRadioGroupOrientation = 'vertical';\n\n @property({ type: Boolean, reflect: true })\n invalid = false;\n\n @property()\n label = '';\n\n @property()\n instructions = '';\n\n @property({ attribute: 'aria-label' })\n override ariaLabel: string | null = null;\n\n @query('slot:not([name])')\n private defaultSlot!: HTMLSlotElement;\n\n @state()\n private items: PkRadio[] = [];\n\n protected override syncFormValue(): void {\n this.setFormValue(this.value || null);\n }\n\n protected override resetToDefaultValue(): void {\n this._value = null;\n this.applySelection();\n }\n\n protected override restoreFormState(state: string | File | FormData | null): void {\n if (typeof state === 'string') {\n this.value = state;\n this.applySelection();\n }\n }\n\n protected override get validationTarget(): HTMLElement | undefined {\n return this.getAllRadios().find((item) => !item.disabled) ?? this.getAllRadios()[0];\n }\n\n override connectedCallback(): void {\n this.instructions = readLegacyInstructions(this, this.instructions);\n super.connectedCallback();\n this.addEventListener('keydown', this.handleKeyDown);\n this.addEventListener('click', this.handleRadioClick);\n }\n\n override disconnectedCallback(): void {\n this.removeEventListener('keydown', this.handleKeyDown);\n this.removeEventListener('click', this.handleRadioClick);\n super.disconnectedCallback();\n }\n\n override updated(changed: PropertyValues): void {\n if (changed.has('value') || changed.has('disabled') || changed.has('invalid') || changed.has('name')) {\n this.applySelection();\n }\n\n super.updated(changed);\n }\n\n override formResetCallback(): void {\n this._value = null;\n super.formResetCallback();\n this.applySelection();\n }\n\n override focus(options?: FocusOptions): void {\n if (this.disabled) {\n return;\n }\n\n const radios = this.getEnabledItems();\n const checked = radios.find((radio) => radio.checked);\n const target = checked ?? radios[0];\n target?.focusControl(options);\n }\n\n private getAllRadios(): PkRadio[] {\n return [...this.querySelectorAll('pk-radio')];\n }\n\n private syncItems = (): void => {\n this.items = this.getAllRadios();\n this.applySelection();\n };\n\n private getEnabledItems(): PkRadio[] {\n return this.items.filter((item) => !item.disabled && !this.disabled);\n }\n\n private applySelection(): void {\n const radios = this.getAllRadios();\n this.items = radios;\n\n const enabled = this.getEnabledItems();\n const checkedRadio = enabled.find((item) => item.value === this.value);\n\n for (const item of radios) {\n const checked = item.value === this.value;\n // React sets CE booleans as properties, while hand-written HTML uses attributes.\n // Preserve item-level disabled state from either source, but do not let a prior\n // group-level disabled pass permanently mark every child disabled.\n const itemDisabled = item.hasAttribute('disabled') || (item.disabled && !item.forceDisabled);\n item.checked = checked;\n item.disabled = this.disabled || itemDisabled;\n item.invalid = this.invalid;\n item.required = this.required;\n item.forceDisabled = this.disabled;\n }\n\n if (this.disabled) {\n for (const item of radios) {\n item.tabIndex = -1;\n }\n return;\n }\n\n if (checkedRadio) {\n for (const item of enabled) {\n item.tabIndex = item.checked ? 0 : -1;\n }\n } else if (enabled.length > 0) {\n enabled.forEach((item, index) => {\n item.tabIndex = index === 0 ? 0 : -1;\n });\n }\n\n for (const item of radios.filter((radio) => radio.disabled)) {\n item.tabIndex = -1;\n }\n }\n\n private handleRadioClick = (event: Event): void => {\n const clickedRadio = (event.target as HTMLElement).closest('pk-radio') as PkRadio | null;\n\n if (!clickedRadio || clickedRadio.disabled || clickedRadio.forceDisabled || this.disabled) {\n return;\n }\n\n const oldValue = this.value;\n this.value = clickedRadio.value;\n this.applySelection();\n\n if (this.value !== oldValue) {\n this.emitValueChange();\n }\n };\n\n private handleKeyDown = (event: KeyboardEvent): void => {\n if (!['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', ' ', 'Home', 'End'].includes(event.key) || this.disabled) {\n return;\n }\n\n const radios = this.getEnabledItems();\n\n if (radios.length === 0) {\n return;\n }\n\n event.preventDefault();\n\n const oldValue = this.value;\n const checkedRadio = radios.find((radio) => radio.checked) ?? radios[0]!;\n let index = radios.indexOf(checkedRadio);\n\n if (event.key === ' ') {\n // Space selects focused radio without moving\n } else if (event.key === 'Home') {\n index = 0;\n } else if (event.key === 'End') {\n index = radios.length - 1;\n } else {\n const increment = ['ArrowUp', 'ArrowLeft'].includes(event.key) ? -1 : 1;\n index += increment;\n\n if (index < 0) {\n index = radios.length - 1;\n }\n\n if (index >= radios.length) {\n index = 0;\n }\n }\n\n this.value = radios[index]!.value;\n this.applySelection();\n radios[index]!.focusControl();\n\n if (this.value !== oldValue) {\n this.emitValueChange();\n }\n };\n\n private emitValueChange(): void {\n this.dispatchEvent(new CustomEvent('pk-change', {\n detail: { value: this.value },\n bubbles: true,\n composed: true,\n }));\n\n this.dispatchEvent(new Event('input', { bubbles: true, composed: true }));\n this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));\n }\n\n override render() {\n const hasLabelSlot = this.hasSlotController.test('label');\n const hasInstructions = hasInstructionContent(\n (name, flag) => this.hasSlotController.test(name, flag),\n this.instructions,\n );\n const hasLabel = Boolean(this.label) || hasLabelSlot;\n\n return html`\n <div part=\"form-control\" class=\"form-control\">\n ${hasLabel\n ? html`\n <div part=\"label\" class=\"form-control__label\" id=\"label\">\n <slot name=\"label\">${this.label}</slot>\n </div>\n `\n : nothing}\n\n ${hasInstructions\n ? html`\n <div part=\"instructions\" class=\"form-control__instructions\" id=\"instructions\">\n <slot name=\"instructions\">${this.instructions}</slot>\n <slot name=\"hint\"></slot>\n </div>\n `\n : nothing}\n\n <div\n part=\"radios\"\n class=${classMap({\n group: true,\n 'pk-radio-group': true,\n 'group--horizontal': this.orientation === 'horizontal',\n 'pk-radio-group--horizontal': this.orientation === 'horizontal',\n })}\n role=\"radiogroup\"\n aria-labelledby=${hasLabel ? 'label' : nothing}\n aria-label=${!hasLabel ? (this.ariaLabel ?? nothing) : nothing}\n aria-describedby=${hasInstructions ? 'instructions' : nothing}\n aria-invalid=${this.invalid ? 'true' : nothing}\n aria-required=${this.required ? 'true' : nothing}\n >\n <slot @slotchange=${this.syncItems}></slot>\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'pk-radio-group': PkRadioGroup;\n }\n}\n"],"mappings":"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"}
|