@rotki/ui-library 3.0.0-beta.5 → 3.1.0

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.
Files changed (163) hide show
  1. package/dist/components/accordions/accordion/RuiAccordion.js.map +1 -1
  2. package/dist/components/accordions/accordion/RuiAccordion.vue_vue_type_script_setup_true_lang.js +13 -2
  3. package/dist/components/accordions/accordion/RuiAccordion.vue_vue_type_script_setup_true_lang.js.map +1 -1
  4. package/dist/components/alerts/RuiAlert.vue.d.ts +2 -2
  5. package/dist/components/buttons/button/RuiButton.js.map +1 -1
  6. package/dist/components/buttons/button/RuiButton.vue.d.ts +7 -1
  7. package/dist/components/buttons/button/RuiButton.vue_vue_type_script_setup_true_lang.js +4 -2
  8. package/dist/components/buttons/button/RuiButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  9. package/dist/components/buttons/button/button-props.d.ts +3 -0
  10. package/dist/components/buttons/button/button-props.js +2 -1
  11. package/dist/components/buttons/button/button-props.js.map +1 -1
  12. package/dist/components/buttons/button/button-styles.d.ts +75 -0
  13. package/dist/components/buttons/button/button-styles.js +135 -4
  14. package/dist/components/buttons/button/button-styles.js.map +1 -1
  15. package/dist/components/cards/RuiCard.js.map +1 -1
  16. package/dist/components/cards/RuiCard.vue.d.ts +6 -0
  17. package/dist/components/cards/RuiCard.vue_vue_type_script_setup_true_lang.js +14 -2
  18. package/dist/components/cards/RuiCard.vue_vue_type_script_setup_true_lang.js.map +1 -1
  19. package/dist/components/chips/RuiChip.js.map +1 -1
  20. package/dist/components/chips/RuiChip.vue_vue_type_script_setup_true_lang.js +14 -0
  21. package/dist/components/chips/RuiChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  22. package/dist/components/chips/chip-props.d.ts +2 -0
  23. package/dist/components/chips/chip-props.js +3 -0
  24. package/dist/components/chips/chip-props.js.map +1 -1
  25. package/dist/components/color-picker/RuiColorInput.js.map +1 -1
  26. package/dist/components/color-picker/RuiColorInput.vue_vue_type_script_setup_true_lang.js +2 -2
  27. package/dist/components/color-picker/RuiColorInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  28. package/dist/components/date-time-picker/RuiDateTimePicker.js.map +1 -1
  29. package/dist/components/date-time-picker/RuiDateTimePicker.vue.d.ts +4 -0
  30. package/dist/components/date-time-picker/RuiDateTimePicker.vue_vue_type_script_setup_true_lang.js +6 -2
  31. package/dist/components/date-time-picker/RuiDateTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  32. package/dist/components/date-time-picker/RuiDateTimePickerMenu.js.map +1 -1
  33. package/dist/components/date-time-picker/RuiDateTimePickerMenu.vue_vue_type_script_setup_true_lang.js +1 -1
  34. package/dist/components/date-time-picker/RuiDateTimePickerMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  35. package/dist/components/date-time-picker/RuiTimezoneSelect.js.map +1 -1
  36. package/dist/components/date-time-picker/RuiTimezoneSelect.vue.d.ts +4 -0
  37. package/dist/components/date-time-picker/RuiTimezoneSelect.vue_vue_type_script_setup_true_lang.js +3 -2
  38. package/dist/components/date-time-picker/RuiTimezoneSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  39. package/dist/components/forms/auto-complete/RuiAutoComplete.js.map +1 -1
  40. package/dist/components/forms/auto-complete/RuiAutoComplete.vue_vue_type_script_setup_true_lang.js +6 -2
  41. package/dist/components/forms/auto-complete/RuiAutoComplete.vue_vue_type_script_setup_true_lang.js.map +1 -1
  42. package/dist/components/forms/auto-complete/RuiAutoCompleteSelection.js.map +1 -1
  43. package/dist/components/forms/auto-complete/RuiAutoCompleteSelection.vue_vue_type_script_setup_true_lang.js +9 -6
  44. package/dist/components/forms/auto-complete/RuiAutoCompleteSelection.vue_vue_type_script_setup_true_lang.js.map +1 -1
  45. package/dist/components/forms/auto-complete/auto-complete-props.d.ts +4 -0
  46. package/dist/components/forms/category-picker/RuiCategoryPicker.js.map +1 -1
  47. package/dist/components/forms/category-picker/RuiCategoryPicker.vue.d.ts +4 -1
  48. package/dist/components/forms/category-picker/RuiCategoryPicker.vue_vue_type_script_setup_true_lang.js +7 -4
  49. package/dist/components/forms/category-picker/RuiCategoryPicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  50. package/dist/components/forms/check-control-styles.d.ts +27 -0
  51. package/dist/components/forms/check-control-styles.js +26 -1
  52. package/dist/components/forms/check-control-styles.js.map +1 -1
  53. package/dist/components/forms/checkbox/RuiCheckbox.js.map +1 -1
  54. package/dist/components/forms/checkbox/RuiCheckbox.vue.d.ts +6 -0
  55. package/dist/components/forms/checkbox/RuiCheckbox.vue_vue_type_script_setup_true_lang.js +14 -4
  56. package/dist/components/forms/checkbox/RuiCheckbox.vue_vue_type_script_setup_true_lang.js.map +1 -1
  57. package/dist/components/forms/checkbox/checkbox-group/RuiCheckboxGroup.js.map +1 -1
  58. package/dist/components/forms/checkbox/checkbox-group/RuiCheckboxGroup.vue.d.ts +4 -0
  59. package/dist/components/forms/checkbox/checkbox-group/RuiCheckboxGroup.vue_vue_type_script_setup_true_lang.js +7 -2
  60. package/dist/components/forms/checkbox/checkbox-group/RuiCheckboxGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  61. package/dist/components/forms/field-defaults/RuiFieldDefaults.js.map +1 -1
  62. package/dist/components/forms/field-defaults/RuiFieldDefaults.vue.d.ts +3 -0
  63. package/dist/components/forms/field-defaults/RuiFieldDefaults.vue_vue_type_script_setup_true_lang.js +8 -2
  64. package/dist/components/forms/field-defaults/RuiFieldDefaults.vue_vue_type_script_setup_true_lang.js.map +1 -1
  65. package/dist/components/forms/file-upload/RuiFileUpload.js.map +1 -1
  66. package/dist/components/forms/file-upload/RuiFileUpload.vue.d.ts +4 -1
  67. package/dist/components/forms/file-upload/RuiFileUpload.vue_vue_type_script_setup_true_lang.js +10 -3
  68. package/dist/components/forms/file-upload/RuiFileUpload.vue_vue_type_script_setup_true_lang.js.map +1 -1
  69. package/dist/components/forms/radio-button/radio/RuiRadio.js.map +1 -1
  70. package/dist/components/forms/radio-button/radio/RuiRadio.vue.d.ts +6 -0
  71. package/dist/components/forms/radio-button/radio/RuiRadio.vue_vue_type_script_setup_true_lang.js +14 -3
  72. package/dist/components/forms/radio-button/radio/RuiRadio.vue_vue_type_script_setup_true_lang.js.map +1 -1
  73. package/dist/components/forms/radio-button/radio-group/RuiRadioGroup.js.map +1 -1
  74. package/dist/components/forms/radio-button/radio-group/RuiRadioGroup.vue.d.ts +4 -0
  75. package/dist/components/forms/radio-button/radio-group/RuiRadioGroup.vue_vue_type_script_setup_true_lang.js +7 -2
  76. package/dist/components/forms/radio-button/radio-group/RuiRadioGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  77. package/dist/components/forms/revealable-text-field/RuiRevealableTextField.js.map +1 -1
  78. package/dist/components/forms/revealable-text-field/RuiRevealableTextField.vue_vue_type_script_setup_true_lang.js +3 -2
  79. package/dist/components/forms/revealable-text-field/RuiRevealableTextField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  80. package/dist/components/forms/select/RuiMenuSelect.js.map +1 -1
  81. package/dist/components/forms/select/RuiMenuSelect.vue.d.ts +4 -0
  82. package/dist/components/forms/select/RuiMenuSelect.vue_vue_type_script_setup_true_lang.js +6 -2
  83. package/dist/components/forms/select/RuiMenuSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  84. package/dist/components/forms/slider/RuiSlider.js.map +1 -1
  85. package/dist/components/forms/slider/RuiSlider.vue.d.ts +4 -0
  86. package/dist/components/forms/slider/RuiSlider.vue_vue_type_script_setup_true_lang.js +6 -3
  87. package/dist/components/forms/slider/RuiSlider.vue_vue_type_script_setup_true_lang.js.map +1 -1
  88. package/dist/components/forms/switch/RuiSwitch.js.map +1 -1
  89. package/dist/components/forms/switch/RuiSwitch.vue.d.ts +6 -0
  90. package/dist/components/forms/switch/RuiSwitch.vue_vue_type_script_setup_true_lang.js +25 -5
  91. package/dist/components/forms/switch/RuiSwitch.vue_vue_type_script_setup_true_lang.js.map +1 -1
  92. package/dist/components/forms/text-area/RuiTextArea.js.map +1 -1
  93. package/dist/components/forms/text-area/RuiTextArea.vue.d.ts +4 -0
  94. package/dist/components/forms/text-area/RuiTextArea.vue_vue_type_script_setup_true_lang.js +6 -4
  95. package/dist/components/forms/text-area/RuiTextArea.vue_vue_type_script_setup_true_lang.js.map +1 -1
  96. package/dist/components/forms/text-area/text-area-styles.d.ts +0 -1
  97. package/dist/components/forms/text-area/text-area-styles.js +0 -1
  98. package/dist/components/forms/text-area/text-area-styles.js.map +1 -1
  99. package/dist/components/forms/text-field/RuiTextField.js.map +1 -1
  100. package/dist/components/forms/text-field/RuiTextField.vue.d.ts +6 -2
  101. package/dist/components/forms/text-field/RuiTextField.vue_vue_type_script_setup_true_lang.js +6 -4
  102. package/dist/components/forms/text-field/RuiTextField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  103. package/dist/components/forms/text-field/text-field-styles.d.ts +0 -1
  104. package/dist/components/forms/text-field/text-field-styles.js +0 -1
  105. package/dist/components/forms/text-field/text-field-styles.js.map +1 -1
  106. package/dist/components/helpers/RuiFormTextDetail.js.map +1 -1
  107. package/dist/components/helpers/RuiFormTextDetail.vue.d.ts +14 -0
  108. package/dist/components/helpers/RuiFormTextDetail.vue_vue_type_script_setup_true_lang.js +41 -11
  109. package/dist/components/helpers/RuiFormTextDetail.vue_vue_type_script_setup_true_lang.js.map +1 -1
  110. package/dist/components/loaders/RuiSkeletonBase.js.map +1 -1
  111. package/dist/components/loaders/RuiSkeletonBase.vue_vue_type_script_setup_true_lang.js.map +1 -1
  112. package/dist/components/overlays/menu/RuiMenu.js.map +1 -1
  113. package/dist/components/overlays/menu/RuiMenu.vue.d.ts +3 -0
  114. package/dist/components/overlays/menu/RuiMenu.vue_vue_type_script_setup_true_lang.js +9 -1
  115. package/dist/components/overlays/menu/RuiMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  116. package/dist/components/tables/RuiDataTable.js.map +1 -1
  117. package/dist/components/tables/RuiDataTable.vue.d.ts +9 -0
  118. package/dist/components/tables/RuiDataTable.vue_vue_type_script_setup_true_lang.js +19 -7
  119. package/dist/components/tables/RuiDataTable.vue_vue_type_script_setup_true_lang.js.map +1 -1
  120. package/dist/components/tables/RuiExpandButton.js.map +1 -1
  121. package/dist/components/tables/RuiExpandButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  122. package/dist/components/tables/RuiTableHead.js.map +1 -1
  123. package/dist/components/tables/RuiTableHead.vue_vue_type_script_setup_true_lang.js +1 -1
  124. package/dist/components/tables/RuiTableHead.vue_vue_type_script_setup_true_lang.js.map +1 -1
  125. package/dist/components/tables/RuiTablePagination.js.map +1 -1
  126. package/dist/components/tables/RuiTablePagination.vue_vue_type_script_setup_true_lang.js +3 -3
  127. package/dist/components/tables/RuiTablePagination.vue_vue_type_script_setup_true_lang.js.map +1 -1
  128. package/dist/components/tables/data-table/RuiDataTableAppendRow.js.map +1 -1
  129. package/dist/components/tables/data-table/RuiDataTableAppendRow.vue_vue_type_script_setup_true_lang.js.map +1 -1
  130. package/dist/components/tables/data-table/RuiDataTableBody.js.map +1 -1
  131. package/dist/components/tables/data-table/RuiDataTableBody.vue_vue_type_script_setup_true_lang.js +4 -3
  132. package/dist/components/tables/data-table/RuiDataTableBody.vue_vue_type_script_setup_true_lang.js.map +1 -1
  133. package/dist/components/tables/data-table/RuiDataTableRow.js.map +1 -1
  134. package/dist/components/tables/data-table/RuiDataTableRow.vue_vue_type_script_setup_true_lang.js +4 -4
  135. package/dist/components/tables/data-table/RuiDataTableRow.vue_vue_type_script_setup_true_lang.js.map +1 -1
  136. package/dist/components/tables/data-table-styles.d.ts +6 -0
  137. package/dist/components/tables/data-table-styles.js +15 -7
  138. package/dist/components/tables/data-table-styles.js.map +1 -1
  139. package/dist/components/tabs/tab-items/RuiTabItems.js.map +1 -1
  140. package/dist/components/tabs/tab-items/RuiTabItems.vue_vue_type_script_setup_true_lang.js +9 -2
  141. package/dist/components/tabs/tab-items/RuiTabItems.vue_vue_type_script_setup_true_lang.js.map +1 -1
  142. package/dist/composables/clip-while-resizing.d.ts +15 -0
  143. package/dist/composables/clip-while-resizing.js +46 -0
  144. package/dist/composables/clip-while-resizing.js.map +1 -0
  145. package/dist/composables/defaults/field.d.ts +19 -3
  146. package/dist/composables/defaults/field.js +32 -6
  147. package/dist/composables/defaults/field.js.map +1 -1
  148. package/dist/composables/sticky-blocker.d.ts +20 -0
  149. package/dist/composables/sticky-blocker.js +62 -0
  150. package/dist/composables/sticky-blocker.js.map +1 -0
  151. package/dist/composables/tables/data-table/page-scroll.js +11 -1
  152. package/dist/composables/tables/data-table/page-scroll.js.map +1 -1
  153. package/dist/index.d.ts +6 -2
  154. package/dist/index.js.map +1 -1
  155. package/dist/style.css +352 -11
  156. package/dist/utils/development.d.ts +6 -0
  157. package/dist/utils/development.js +17 -0
  158. package/dist/utils/development.js.map +1 -0
  159. package/dist/utils/form-text-detail.d.ts +15 -0
  160. package/dist/utils/form-text-detail.js +11 -1
  161. package/dist/utils/form-text-detail.js.map +1 -1
  162. package/dist/web-types.json +242 -3
  163. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"button-styles.js","names":[],"sources":["../../../../src/components/buttons/button/button-styles.ts"],"sourcesContent":["import { tv } from '@/utils/tv';\n\n/**\n * The button's classes.\n *\n * Three decisions the class lists cannot state themselves:\n *\n * `position: relative` is not in the base root: it is only a positioning\n * context for the loading spinner, so the `loading` variant applies it.\n * Basing it here would collide with consumers pinning the button with\n * `fixed`/`absolute`, since cascade order picks the later utility, usually\n * `relative`, and turns their `right-*`/`bottom-*` into relative offsets,\n * which misplaces FABs.\n *\n * Icon sizing flows through the `--rui-icon-size` custom property, seeded at\n * the md value in the base root and redefined per size variant with `!` so a\n * variant beats the baseline on the same element regardless of source order.\n * RuiIcon's own `size` prop stamps an inline style on the svg, which beats the\n * inherited value, so a consumer always wins. See rotki/ui-library#512.\n *\n * `disabled` on the element covers two states: actually disabled, and loading,\n * since RuiButton sets `disabled = disabled || loading`. Only the cursor is\n * shared between them; the grey disabled palette lives in the `loading: false`\n * compounds, so a loading button keeps its variant color behind the spinner.\n *\n * An icon-only button matches the height of the text button of the same size,\n * with a 60-70% glyph ratio, which is a larger glyph than the same size gives\n * a prepend/append icon so it does not look lost in the square. xs pads by an\n * arbitrary 0.1875rem because no Tailwind token holds the ratio at a 14px\n * glyph:\n *\n * ```\n * xs p-[0.1875rem] + 0.875rem icon = 1.25rem (20px) 70%\n * sm p-1 + 1.25rem icon = 1.75rem (28px) 71%\n * md (default) p-2 + 1.25rem icon = 2.25rem (36px) 56%\n * lg p-1.5 + 1.5rem icon = 2.25rem (36px) 67%\n * xl p-2 + 1.5rem icon = 2.5rem (40px) 60%\n * 2xl p-2 + 1.75rem icon = 2.75rem (44px) 64%\n * ```\n */\nexport const buttonStyles = tv({\n slots: {\n root: [\n 'text-sm leading-5 font-medium inset-ring inset-ring-transparent',\n 'flex items-center justify-center gap-x-2',\n // md is 36px, the height of a text field or select, so a button lines up with them in a row\n 'px-4 py-2 rounded-rui-control transition-colors duration-150',\n '[--rui-icon-size:1rem]',\n 'disabled:cursor-not-allowed',\n 'focus-visible:focus-ring',\n ].join(' '),\n label: 'inline-block text-nowrap',\n // inline in the prepend icon's place; an icon-only button centers it over its hidden glyph instead\n spinner: 'shrink-0',\n },\n variants: {\n variant: {\n default: {},\n outlined: {},\n text: { root: 'px-2' },\n fab: { root: 'rounded-full py-2 shadow-rui-control disabled:shadow-none' },\n // The label's 16px line-box matches the md icon box, so the two share an optical center (rotki/ui-library#515)\n list: { root: 'p-3 px-3 rounded-rui-sm w-full justify-start text-left', label: 'w-full leading-4' },\n },\n size: {\n 'xs': { root: 'px-2 py-[0.125rem] text-[.75rem] leading-4 ![--rui-icon-size:0.75rem]' },\n 'sm': { root: 'px-2.5 py-1 text-[.8125rem] leading-5 ![--rui-icon-size:0.875rem]' },\n 'lg': { root: 'px-6 py-2 text-[1rem] leading-5 ![--rui-icon-size:1.25rem]' },\n // 40px, to line up with RuiTextField / RuiMenuSelect in a toolbar; a 44px jumbo CTA is `2xl`\n 'xl': { root: 'px-6 py-2 text-[1rem] leading-6 ![--rui-icon-size:1.375rem]' },\n '2xl': { root: 'px-6 py-2.5 text-[1rem] leading-6 ![--rui-icon-size:1.375rem]' },\n },\n color: {\n grey: { root: 'bg-rui-neutral-100 hover:bg-rui-neutral-200 active:bg-rui-neutral-300 text-rui-text dark:bg-rui-neutral-800 dark:hover:bg-rui-neutral-700 dark:active:bg-rui-neutral-600' },\n // hover is a tint laid over the fill (see the filled compound below); pressed sinks to `darker`\n primary: { root: 'bg-rui-primary active:bg-rui-primary-darker text-rui-dark-text dark:text-rui-text' },\n secondary: { root: 'bg-rui-secondary active:bg-rui-secondary-darker text-rui-dark-text dark:text-rui-text' },\n error: { root: 'bg-rui-error active:bg-rui-error-darker text-rui-dark-text dark:text-rui-text' },\n warning: { root: 'bg-rui-warning active:bg-rui-warning-darker text-rui-dark-text dark:text-rui-text' },\n info: { root: 'bg-rui-info active:bg-rui-info-darker text-rui-dark-text dark:text-rui-text' },\n success: { root: 'bg-rui-success active:bg-rui-success-darker text-rui-dark-text dark:text-rui-text' },\n },\n rounded: {\n true: { root: 'rounded-full' },\n },\n icon: {\n /*\n * Only the round shape; the `icon + size` compounds below carry padding and icon sizing. The\n * label holds no text, so it lays out as a flex box: a line box would put a wrapped icon (a\n * badge) on the text baseline and grow the button by the descender gap.\n */\n true: { root: 'rounded-full', label: 'inline-flex' },\n },\n active: {\n true: {},\n false: {},\n },\n loading: {\n true: { root: 'relative !cursor-progress' },\n false: {},\n },\n hideFocusIndicator: {\n true: { root: 'focus-visible:!outline-hidden' },\n },\n },\n compoundVariants: [\n /*\n * Filled hover: the pressed state layer (10% black in light, 12% white in dark) over the fill, a\n * step of about a tenth rather than the jump to `darker`, which stays for the pressed state.\n * `not-disabled:` keeps a disabled or loading button flat; an `<a>` is never `:disabled`.\n */\n { variant: ['default', 'fab'], color: ['primary', 'secondary', 'error', 'warning', 'info', 'success'], class: { root: 'not-disabled:hover:state-layer-pressed' } },\n // An icon-only button has no label to keep, so its glyph goes transparent (still in the accessibility tree) under a centered spinner\n { loading: true, icon: true, class: { root: '[&>*:not([data-spinner])]:opacity-0', spinner: 'absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2' } },\n // Disabled appearance: a flat neutral fill, skipped while loading so the variant color shows behind the spinner\n { loading: false, class: { root: 'disabled:!bg-rui-neutral-100 dark:disabled:!bg-rui-neutral-800 disabled:!text-rui-text-disabled disabled:active:!text-rui-text-disabled' } },\n { loading: false, variant: 'outlined', class: { root: 'disabled:!bg-transparent dark:disabled:!bg-transparent disabled:active:!bg-transparent disabled:inset-ring-rui-text-disabled dark:disabled:inset-ring-rui-text-disabled' } },\n { loading: false, variant: 'text', class: { root: 'disabled:!bg-transparent dark:disabled:!bg-transparent disabled:active:!bg-transparent' } },\n { loading: false, variant: 'list', class: { root: 'disabled:!bg-transparent dark:disabled:!bg-transparent disabled:active:!bg-transparent' } },\n\n // === Grey color variants ===\n { color: 'grey', active: true, class: { root: 'bg-rui-neutral-200 dark:bg-rui-neutral-700' } },\n // the same hover and pressed tints as a highlighted menu option\n { color: 'grey', variant: ['outlined', 'text', 'list'], class: { root: 'bg-transparent hover:bg-rui-hover active:bg-rui-pressed dark:bg-transparent dark:text-rui-text' } },\n { color: 'grey', variant: ['outlined', 'text', 'list'], active: true, class: { root: 'bg-rui-pressed dark:bg-rui-pressed' } },\n // the shared control edge, 3:1 against the page like the 50% context colours beside it\n { color: 'grey', variant: 'outlined', class: { root: 'inset-ring-rui-outline' } },\n { color: 'grey', variant: 'text', class: { root: 'text-rui-text-secondary' } },\n\n // `dark:text-rui-<color>` beats the filled buttons' `dark:text-rui-text`; primary, secondary and error use their lighter tone in dark for 4.5:1\n { color: 'primary', variant: ['outlined', 'text', 'list'], class: { root: 'bg-transparent hover:bg-rui-primary/6 active:bg-rui-primary/10 text-rui-primary dark:text-rui-primary-lighter' } },\n { color: 'secondary', variant: ['outlined', 'text', 'list'], class: { root: 'bg-transparent hover:bg-rui-secondary/6 active:bg-rui-secondary/10 text-rui-secondary dark:text-rui-secondary-lighter' } },\n { color: 'error', variant: ['outlined', 'text', 'list'], class: { root: 'bg-transparent hover:bg-rui-error/6 active:bg-rui-error/10 text-rui-error dark:text-rui-error-lighter' } },\n { color: 'warning', variant: ['outlined', 'text', 'list'], class: { root: 'bg-transparent hover:bg-rui-warning/6 active:bg-rui-warning/10 text-rui-warning dark:text-rui-warning' } },\n { color: 'info', variant: ['outlined', 'text', 'list'], class: { root: 'bg-transparent hover:bg-rui-info/6 active:bg-rui-info/10 text-rui-info dark:text-rui-info' } },\n { color: 'success', variant: ['outlined', 'text', 'list'], class: { root: 'bg-transparent hover:bg-rui-success/6 active:bg-rui-success/10 text-rui-success dark:text-rui-success' } },\n\n // === Context colors — active default ===\n { color: 'primary', active: true, class: { root: 'bg-rui-primary-darker' } },\n { color: 'secondary', active: true, class: { root: 'bg-rui-secondary-darker' } },\n { color: 'error', active: true, class: { root: 'bg-rui-error-darker' } },\n { color: 'warning', active: true, class: { root: 'bg-rui-warning-darker' } },\n { color: 'info', active: true, class: { root: 'bg-rui-info-darker' } },\n { color: 'success', active: true, class: { root: 'bg-rui-success-darker' } },\n\n // Active outlined/text: a quiet tint with the deeper tone as the label, which keeps 4.5:1 for every color\n { color: 'primary', variant: ['outlined', 'text', 'list'], active: true, class: { root: 'bg-rui-primary/[0.08] text-rui-primary-darker' } },\n { color: 'secondary', variant: ['outlined', 'text', 'list'], active: true, class: { root: 'bg-rui-secondary/[0.08] text-rui-secondary-darker' } },\n { color: 'error', variant: ['outlined', 'text', 'list'], active: true, class: { root: 'bg-rui-error/[0.08] text-rui-error-darker' } },\n { color: 'warning', variant: ['outlined', 'text', 'list'], active: true, class: { root: 'bg-rui-warning/[0.08] text-rui-warning-darker' } },\n { color: 'info', variant: ['outlined', 'text', 'list'], active: true, class: { root: 'bg-rui-info/[0.08] text-rui-info-darker' } },\n { color: 'success', variant: ['outlined', 'text', 'list'], active: true, class: { root: 'bg-rui-success/[0.08] text-rui-success-darker' } },\n\n // === Context colors: outlined border (dark draws primary and secondary solid; at 50% their deep fills sink into the page and look alike) ===\n { color: 'primary', variant: 'outlined', class: { root: 'inset-ring-rui-primary/50 dark:inset-ring-rui-primary' } },\n { color: 'secondary', variant: 'outlined', class: { root: 'inset-ring-rui-secondary/50 dark:inset-ring-rui-secondary' } },\n { color: 'error', variant: 'outlined', class: { root: 'inset-ring-rui-error/50' } },\n { color: 'warning', variant: 'outlined', class: { root: 'inset-ring-rui-warning/50' } },\n { color: 'info', variant: 'outlined', class: { root: 'inset-ring-rui-info/50' } },\n { color: 'success', variant: 'outlined', class: { root: 'inset-ring-rui-success/50' } },\n\n // === Size overrides per variant ===\n { variant: 'text', size: 'xs', class: { root: 'px-1' } },\n { variant: 'text', size: 'sm', class: { root: 'px-1.5' } },\n { variant: 'text', size: 'lg', class: { root: 'px-2.5' } },\n { variant: 'text', size: 'xl', class: { root: 'px-2.5' } },\n { variant: 'text', size: '2xl', class: { root: 'px-2.5' } },\n { variant: 'fab', size: 'xs', class: { root: 'py-1 px-1' } },\n { variant: 'fab', size: 'sm', class: { root: 'py-1.5 px-2' } },\n { variant: 'fab', size: 'lg', class: { root: 'py-3' } },\n { variant: 'list', size: 'xs', class: { root: 'px-3 py-0.5' } },\n // 32px: a dense select's option row, which `getOptionHeight` reserves in the virtual list\n { variant: 'list', size: 'sm', class: { root: 'px-3 py-2' } },\n // Icon-only sizing, per the padding and glyph table on buttonStyles above\n { icon: true, class: { root: 'p-2 ![--rui-icon-size:1.25rem]' } },\n { icon: true, size: 'xs', class: { root: 'p-[0.1875rem] ![--rui-icon-size:0.875rem]' } },\n { icon: true, size: 'sm', class: { root: 'p-1 ![--rui-icon-size:1.25rem]' } },\n { icon: true, size: 'lg', class: { root: 'p-1.5 ![--rui-icon-size:1.5rem]' } },\n { icon: true, size: 'xl', class: { root: 'p-2 ![--rui-icon-size:1.5rem]' } },\n { icon: true, size: '2xl', class: { root: 'p-2 ![--rui-icon-size:1.75rem]' } },\n { variant: 'fab', icon: true, size: 'sm', class: { root: 'px-2 py-2' } },\n ],\n compoundSlots: [\n // In dark a status color's `main` is a text tone, so a filled status button takes the deep `darker` fill\n { slots: ['root'], color: 'error', variant: ['default', 'fab'], class: 'dark:bg-rui-error-darker dark:active:bg-rui-error-darker/75' },\n { slots: ['root'], color: 'warning', variant: ['default', 'fab'], class: 'dark:bg-rui-warning-darker dark:active:bg-rui-warning-darker/75' },\n { slots: ['root'], color: 'info', variant: ['default', 'fab'], class: 'dark:bg-rui-info-darker dark:active:bg-rui-info-darker/75' },\n { slots: ['root'], color: 'success', variant: ['default', 'fab'], class: 'dark:bg-rui-success-darker dark:active:bg-rui-success-darker/75' },\n // Dark mode active outlined/text: the same quiet tint, with the lighter tone as the label\n { slots: ['root'], color: 'primary', variant: ['outlined', 'text', 'list'], active: true, class: 'dark:bg-rui-primary/[0.16] dark:text-rui-primary-lighter' },\n { slots: ['root'], color: 'secondary', variant: ['outlined', 'text', 'list'], active: true, class: 'dark:bg-rui-secondary/[0.16] dark:text-rui-secondary-lighter' },\n { slots: ['root'], color: 'error', variant: ['outlined', 'text', 'list'], active: true, class: 'dark:bg-rui-error/[0.16] dark:text-rui-error-lighter' },\n { slots: ['root'], color: 'warning', variant: ['outlined', 'text', 'list'], active: true, class: 'dark:bg-rui-warning/[0.16] dark:text-rui-warning-lighter' },\n { slots: ['root'], color: 'info', variant: ['outlined', 'text', 'list'], active: true, class: 'dark:bg-rui-info/[0.16] dark:text-rui-info-lighter' },\n { slots: ['root'], color: 'success', variant: ['outlined', 'text', 'list'], active: true, class: 'dark:bg-rui-success/[0.16] dark:text-rui-success-lighter' },\n ],\n defaultVariants: {\n variant: 'default',\n color: 'grey',\n active: false,\n },\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"button-styles.js","names":[],"sources":["../../../../src/components/buttons/button/button-styles.ts"],"sourcesContent":["import { tv } from '@/utils/tv';\n\n/**\n * The button's classes.\n *\n * Three decisions the class lists cannot state themselves:\n *\n * `position: relative` is not in the base root: it is only a positioning\n * context for the loading spinner, so the `loading` variant applies it.\n * Basing it here would collide with consumers pinning the button with\n * `fixed`/`absolute`, since cascade order picks the later utility, usually\n * `relative`, and turns their `right-*`/`bottom-*` into relative offsets,\n * which misplaces FABs.\n *\n * Icon sizing flows through the `--rui-icon-size` custom property, seeded at\n * the md value in the base root and redefined per size variant with `!` so a\n * variant beats the baseline on the same element regardless of source order.\n * RuiIcon's own `size` prop stamps an inline style on the svg, which beats the\n * inherited value, so a consumer always wins. See rotki/ui-library#512.\n *\n * `disabled` on the element covers two states: actually disabled, and loading,\n * since RuiButton sets `disabled = disabled || loading`. Only the cursor is\n * shared between them; the grey disabled palette lives in the `loading: false`\n * compounds, so a loading button keeps its variant color behind the spinner.\n *\n * An icon-only button matches the height of the text button of the same size,\n * with a 60-70% glyph ratio, which is a larger glyph than the same size gives\n * a prepend/append icon so it does not look lost in the square. xs pads by an\n * arbitrary 0.1875rem because no Tailwind token holds the ratio at a 14px\n * glyph:\n *\n * ```\n * xs p-[0.1875rem] + 0.875rem icon = 1.25rem (20px) 70%\n * sm p-1 + 1.25rem icon = 1.75rem (28px) 71%\n * md (default) p-2 + 1.25rem icon = 2.25rem (36px) 56%\n * lg p-1.5 + 1.5rem icon = 2.25rem (36px) 67%\n * xl p-2 + 1.5rem icon = 2.5rem (40px) 60%\n * 2xl p-2 + 1.75rem icon = 2.75rem (44px) 64%\n * ```\n */\nexport const buttonStyles = tv({\n slots: {\n root: [\n 'text-sm leading-5 font-medium inset-ring inset-ring-transparent',\n 'flex items-center justify-center gap-x-2',\n // md is 36px, the height of a text field or select, so a button lines up with them in a row\n 'px-4 py-2 rounded-rui-control transition-colors duration-150',\n '[--rui-icon-size:1rem]',\n 'disabled:cursor-not-allowed',\n 'focus-visible:focus-ring',\n ].join(' '),\n label: 'inline-block text-nowrap',\n // inline in the prepend icon's place; an icon-only button centers it over its hidden glyph instead\n spinner: 'shrink-0',\n },\n variants: {\n variant: {\n default: {},\n outlined: {},\n text: { root: 'px-2' },\n fab: { root: 'rounded-full py-2 shadow-rui-control disabled:shadow-none' },\n // The label's 16px line-box matches the md icon box, so the two share an optical center (rotki/ui-library#515)\n list: { root: 'p-3 px-3 rounded-rui-sm w-full justify-start text-left', label: 'w-full leading-4' },\n // An action inside running text: no box, so its size, padding and fills are reset in the link compounds at the end\n link: { root: 'inline-flex align-baseline gap-x-1 underline-offset-2 not-disabled:hover:underline' },\n },\n size: {\n 'xs': { root: 'px-2 py-[0.125rem] text-[.75rem] leading-4 ![--rui-icon-size:0.75rem]' },\n 'sm': { root: 'px-2.5 py-1 text-[.8125rem] leading-5 ![--rui-icon-size:0.875rem]' },\n 'lg': { root: 'px-6 py-2 text-[1rem] leading-5 ![--rui-icon-size:1.25rem]' },\n // 40px, to line up with RuiTextField / RuiMenuSelect in a toolbar; a 44px jumbo CTA is `2xl`\n 'xl': { root: 'px-6 py-2 text-[1rem] leading-6 ![--rui-icon-size:1.375rem]' },\n '2xl': { root: 'px-6 py-2.5 text-[1rem] leading-6 ![--rui-icon-size:1.375rem]' },\n },\n color: {\n grey: { root: 'bg-rui-neutral-100 hover:bg-rui-neutral-200 active:bg-rui-neutral-300 text-rui-text dark:bg-rui-neutral-800 dark:hover:bg-rui-neutral-700 dark:active:bg-rui-neutral-600' },\n // hover is a tint laid over the fill (see the filled compound below); pressed sinks to `darker`\n primary: { root: 'bg-rui-primary active:bg-rui-primary-darker text-rui-dark-text dark:text-rui-text' },\n secondary: { root: 'bg-rui-secondary active:bg-rui-secondary-darker text-rui-dark-text dark:text-rui-text' },\n error: { root: 'bg-rui-error active:bg-rui-error-darker text-rui-dark-text dark:text-rui-text' },\n warning: { root: 'bg-rui-warning active:bg-rui-warning-darker text-rui-dark-text dark:text-rui-text' },\n info: { root: 'bg-rui-info active:bg-rui-info-darker text-rui-dark-text dark:text-rui-text' },\n success: { root: 'bg-rui-success active:bg-rui-success-darker text-rui-dark-text dark:text-rui-text' },\n },\n rounded: {\n true: { root: 'rounded-full' },\n },\n icon: {\n /*\n * Only the round shape; the `icon + size` compounds below carry padding and icon sizing. The\n * label holds no text, so it lays out as a flex box: a line box would put a wrapped icon (a\n * badge) on the text baseline and grow the button by the descender gap.\n */\n true: { root: 'rounded-full', label: 'inline-flex' },\n },\n active: {\n true: {},\n false: {},\n },\n loading: {\n true: { root: 'relative !cursor-progress' },\n false: {},\n },\n hideFocusIndicator: {\n true: { root: 'focus-visible:!outline-hidden' },\n },\n /*\n * Below the breakpoint the label turns `sr-only`, so it still names the button, and the button\n * takes its icon-only padding and glyph from the two properties the `collapsed` compounds seed\n * per size. One static list per breakpoint, since Tailwind cannot see a generated class.\n */\n collapseBelow: {\n 'sm': { root: 'max-sm:gap-x-0 max-sm:p-(--rui-btn-collapsed-p) max-sm:![--rui-icon-size:var(--rui-btn-collapsed-icon)]', label: 'max-sm:sr-only' },\n 'md': { root: 'max-md:gap-x-0 max-md:p-(--rui-btn-collapsed-p) max-md:![--rui-icon-size:var(--rui-btn-collapsed-icon)]', label: 'max-md:sr-only' },\n 'lg': { root: 'max-lg:gap-x-0 max-lg:p-(--rui-btn-collapsed-p) max-lg:![--rui-icon-size:var(--rui-btn-collapsed-icon)]', label: 'max-lg:sr-only' },\n 'xl': { root: 'max-xl:gap-x-0 max-xl:p-(--rui-btn-collapsed-p) max-xl:![--rui-icon-size:var(--rui-btn-collapsed-icon)]', label: 'max-xl:sr-only' },\n '2xl': { root: 'max-2xl:gap-x-0 max-2xl:p-(--rui-btn-collapsed-p) max-2xl:![--rui-icon-size:var(--rui-btn-collapsed-icon)]', label: 'max-2xl:sr-only' },\n },\n },\n compoundVariants: [\n /*\n * Filled hover: the pressed state layer (10% black in light, 12% white in dark) over the fill, a\n * step of about a tenth rather than the jump to `darker`, which stays for the pressed state.\n * `not-disabled:` keeps a disabled or loading button flat; an `<a>` is never `:disabled`.\n */\n { variant: ['default', 'fab'], color: ['primary', 'secondary', 'error', 'warning', 'info', 'success'], class: { root: 'not-disabled:hover:state-layer-pressed' } },\n // An icon-only button has no label to keep, so its glyph goes transparent (still in the accessibility tree) under a centered spinner\n { loading: true, icon: true, class: { root: '[&>*:not([data-spinner])]:opacity-0', spinner: 'absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2' } },\n // Disabled appearance: a flat neutral fill, skipped while loading so the variant color shows behind the spinner\n { loading: false, class: { root: 'disabled:!bg-rui-neutral-100 dark:disabled:!bg-rui-neutral-800 disabled:!text-rui-text-disabled disabled:active:!text-rui-text-disabled' } },\n { loading: false, variant: 'outlined', class: { root: 'disabled:!bg-transparent dark:disabled:!bg-transparent disabled:active:!bg-transparent disabled:inset-ring-rui-text-disabled dark:disabled:inset-ring-rui-text-disabled' } },\n { loading: false, variant: ['text', 'link'], class: { root: 'disabled:!bg-transparent dark:disabled:!bg-transparent disabled:active:!bg-transparent' } },\n { loading: false, variant: 'list', class: { root: 'disabled:!bg-transparent dark:disabled:!bg-transparent disabled:active:!bg-transparent' } },\n\n // === Grey color variants ===\n { color: 'grey', active: true, class: { root: 'bg-rui-neutral-200 dark:bg-rui-neutral-700' } },\n // the same hover and pressed tints as a highlighted menu option\n { color: 'grey', variant: ['outlined', 'text', 'list'], class: { root: 'bg-transparent hover:bg-rui-hover active:bg-rui-pressed dark:bg-transparent dark:text-rui-text' } },\n { color: 'grey', variant: ['outlined', 'text', 'list'], active: true, class: { root: 'bg-rui-pressed dark:bg-rui-pressed' } },\n // the shared control edge, 3:1 against the page like the 50% context colours beside it\n { color: 'grey', variant: 'outlined', class: { root: 'inset-ring-rui-outline' } },\n // the dark variant overrides the shared compound's `dark:text-rui-text`, so a grey text button stays secondary in both themes\n { color: 'grey', variant: 'text', class: { root: 'text-rui-text-secondary dark:text-rui-text-secondary' } },\n\n // `dark:text-rui-<color>` beats the filled buttons' `dark:text-rui-text`; primary, secondary and error use their lighter tone in dark for 4.5:1\n { color: 'primary', variant: ['outlined', 'text', 'list'], class: { root: 'bg-transparent hover:bg-rui-primary/6 active:bg-rui-primary/10 text-rui-primary dark:text-rui-primary-lighter' } },\n { color: 'secondary', variant: ['outlined', 'text', 'list'], class: { root: 'bg-transparent hover:bg-rui-secondary/6 active:bg-rui-secondary/10 text-rui-secondary dark:text-rui-secondary-lighter' } },\n { color: 'error', variant: ['outlined', 'text', 'list'], class: { root: 'bg-transparent hover:bg-rui-error/6 active:bg-rui-error/10 text-rui-error dark:text-rui-error-lighter' } },\n { color: 'warning', variant: ['outlined', 'text', 'list'], class: { root: 'bg-transparent hover:bg-rui-warning/6 active:bg-rui-warning/10 text-rui-warning dark:text-rui-warning' } },\n { color: 'info', variant: ['outlined', 'text', 'list'], class: { root: 'bg-transparent hover:bg-rui-info/6 active:bg-rui-info/10 text-rui-info dark:text-rui-info' } },\n { color: 'success', variant: ['outlined', 'text', 'list'], class: { root: 'bg-transparent hover:bg-rui-success/6 active:bg-rui-success/10 text-rui-success dark:text-rui-success' } },\n\n // === Context colors — active default ===\n { color: 'primary', active: true, class: { root: 'bg-rui-primary-darker' } },\n { color: 'secondary', active: true, class: { root: 'bg-rui-secondary-darker' } },\n { color: 'error', active: true, class: { root: 'bg-rui-error-darker' } },\n { color: 'warning', active: true, class: { root: 'bg-rui-warning-darker' } },\n { color: 'info', active: true, class: { root: 'bg-rui-info-darker' } },\n { color: 'success', active: true, class: { root: 'bg-rui-success-darker' } },\n\n // Active outlined/text: a quiet tint with the deeper tone as the label, which keeps 4.5:1 for every color\n { color: 'primary', variant: ['outlined', 'text', 'list'], active: true, class: { root: 'bg-rui-primary/[0.08] text-rui-primary-darker' } },\n { color: 'secondary', variant: ['outlined', 'text', 'list'], active: true, class: { root: 'bg-rui-secondary/[0.08] text-rui-secondary-darker' } },\n { color: 'error', variant: ['outlined', 'text', 'list'], active: true, class: { root: 'bg-rui-error/[0.08] text-rui-error-darker' } },\n { color: 'warning', variant: ['outlined', 'text', 'list'], active: true, class: { root: 'bg-rui-warning/[0.08] text-rui-warning-darker' } },\n { color: 'info', variant: ['outlined', 'text', 'list'], active: true, class: { root: 'bg-rui-info/[0.08] text-rui-info-darker' } },\n { color: 'success', variant: ['outlined', 'text', 'list'], active: true, class: { root: 'bg-rui-success/[0.08] text-rui-success-darker' } },\n\n // === Context colors: outlined border (dark draws primary and secondary solid; at 50% their deep fills sink into the page and look alike) ===\n { color: 'primary', variant: 'outlined', class: { root: 'inset-ring-rui-primary/50 dark:inset-ring-rui-primary' } },\n { color: 'secondary', variant: 'outlined', class: { root: 'inset-ring-rui-secondary/50 dark:inset-ring-rui-secondary' } },\n { color: 'error', variant: 'outlined', class: { root: 'inset-ring-rui-error/50' } },\n { color: 'warning', variant: 'outlined', class: { root: 'inset-ring-rui-warning/50' } },\n { color: 'info', variant: 'outlined', class: { root: 'inset-ring-rui-info/50' } },\n { color: 'success', variant: 'outlined', class: { root: 'inset-ring-rui-success/50' } },\n\n // === Size overrides per variant ===\n { variant: 'text', size: 'xs', class: { root: 'px-1' } },\n { variant: 'text', size: 'sm', class: { root: 'px-1.5' } },\n { variant: 'text', size: 'lg', class: { root: 'px-2.5' } },\n { variant: 'text', size: 'xl', class: { root: 'px-2.5' } },\n { variant: 'text', size: '2xl', class: { root: 'px-2.5' } },\n { variant: 'fab', size: 'xs', class: { root: 'py-1 px-1' } },\n { variant: 'fab', size: 'sm', class: { root: 'py-1.5 px-2' } },\n { variant: 'fab', size: 'lg', class: { root: 'py-3' } },\n { variant: 'list', size: 'xs', class: { root: 'px-3 py-0.5' } },\n // 32px: a dense select's option row, which `getOptionHeight` reserves in the virtual list\n { variant: 'list', size: 'sm', class: { root: 'px-3 py-2' } },\n // Icon-only sizing, per the padding and glyph table on buttonStyles above\n { icon: true, class: { root: 'p-2 ![--rui-icon-size:1.25rem]' } },\n { icon: true, size: 'xs', class: { root: 'p-[0.1875rem] ![--rui-icon-size:0.875rem]' } },\n { icon: true, size: 'sm', class: { root: 'p-1 ![--rui-icon-size:1.25rem]' } },\n { icon: true, size: 'lg', class: { root: 'p-1.5 ![--rui-icon-size:1.5rem]' } },\n { icon: true, size: 'xl', class: { root: 'p-2 ![--rui-icon-size:1.5rem]' } },\n { icon: true, size: '2xl', class: { root: 'p-2 ![--rui-icon-size:1.75rem]' } },\n { variant: 'fab', icon: true, size: 'sm', class: { root: 'px-2 py-2' } },\n // A collapsed button's icon-only padding and glyph, the same table as `icon` above\n { collapseBelow: ['sm', 'md', 'lg', 'xl', '2xl'], class: { root: '[--rui-btn-collapsed-p:0.5rem] [--rui-btn-collapsed-icon:1.25rem]' } },\n { collapseBelow: ['sm', 'md', 'lg', 'xl', '2xl'], size: 'xs', class: { root: '[--rui-btn-collapsed-p:0.1875rem] [--rui-btn-collapsed-icon:0.875rem]' } },\n { collapseBelow: ['sm', 'md', 'lg', 'xl', '2xl'], size: 'sm', class: { root: '[--rui-btn-collapsed-p:0.25rem] [--rui-btn-collapsed-icon:1.25rem]' } },\n { collapseBelow: ['sm', 'md', 'lg', 'xl', '2xl'], size: 'lg', class: { root: '[--rui-btn-collapsed-p:0.375rem] [--rui-btn-collapsed-icon:1.5rem]' } },\n { collapseBelow: ['sm', 'md', 'lg', 'xl', '2xl'], size: 'xl', class: { root: '[--rui-btn-collapsed-p:0.5rem] [--rui-btn-collapsed-icon:1.5rem]' } },\n { collapseBelow: ['sm', 'md', 'lg', 'xl', '2xl'], size: '2xl', class: { root: '[--rui-btn-collapsed-p:0.5rem] [--rui-btn-collapsed-icon:1.75rem]' } },\n\n /*\n * === Link ===\n * Last, so they win over the size, colour and active entries above. The font size and line height\n * come from the surrounding text and the icons follow it; a size only changes the spinner. The\n * colour is the text tone of the outlined/text compounds, with no fill or tint in any state.\n */\n {\n variant: 'link',\n class: {\n root: [\n 'p-0 text-[length:inherit] leading-[inherit] ![--rui-icon-size:1em]',\n 'bg-transparent hover:bg-transparent active:bg-transparent',\n 'dark:bg-transparent dark:hover:bg-transparent dark:active:bg-transparent',\n ].join(' '),\n },\n },\n { color: 'grey', variant: 'link', class: { root: 'text-rui-text dark:text-rui-text' } },\n { color: 'primary', variant: 'link', class: { root: 'text-rui-primary dark:text-rui-primary-lighter' } },\n { color: 'secondary', variant: 'link', class: { root: 'text-rui-secondary dark:text-rui-secondary-lighter' } },\n { color: 'error', variant: 'link', class: { root: 'text-rui-error dark:text-rui-error-lighter' } },\n { color: 'warning', variant: 'link', class: { root: 'text-rui-warning dark:text-rui-warning' } },\n { color: 'info', variant: 'link', class: { root: 'text-rui-info dark:text-rui-info' } },\n { color: 'success', variant: 'link', class: { root: 'text-rui-success dark:text-rui-success' } },\n ],\n compoundSlots: [\n // In dark a status color's `main` is a text tone, so a filled status button takes the deep `darker` fill\n { slots: ['root'], color: 'error', variant: ['default', 'fab'], class: 'dark:bg-rui-error-darker dark:active:bg-rui-error-darker/75' },\n { slots: ['root'], color: 'warning', variant: ['default', 'fab'], class: 'dark:bg-rui-warning-darker dark:active:bg-rui-warning-darker/75' },\n { slots: ['root'], color: 'info', variant: ['default', 'fab'], class: 'dark:bg-rui-info-darker dark:active:bg-rui-info-darker/75' },\n { slots: ['root'], color: 'success', variant: ['default', 'fab'], class: 'dark:bg-rui-success-darker dark:active:bg-rui-success-darker/75' },\n // Dark mode active outlined/text: the same quiet tint, with the lighter tone as the label\n { slots: ['root'], color: 'primary', variant: ['outlined', 'text', 'list'], active: true, class: 'dark:bg-rui-primary/[0.16] dark:text-rui-primary-lighter' },\n { slots: ['root'], color: 'secondary', variant: ['outlined', 'text', 'list'], active: true, class: 'dark:bg-rui-secondary/[0.16] dark:text-rui-secondary-lighter' },\n { slots: ['root'], color: 'error', variant: ['outlined', 'text', 'list'], active: true, class: 'dark:bg-rui-error/[0.16] dark:text-rui-error-lighter' },\n { slots: ['root'], color: 'warning', variant: ['outlined', 'text', 'list'], active: true, class: 'dark:bg-rui-warning/[0.16] dark:text-rui-warning-lighter' },\n { slots: ['root'], color: 'info', variant: ['outlined', 'text', 'list'], active: true, class: 'dark:bg-rui-info/[0.16] dark:text-rui-info-lighter' },\n { slots: ['root'], color: 'success', variant: ['outlined', 'text', 'list'], active: true, class: 'dark:bg-rui-success/[0.16] dark:text-rui-success-lighter' },\n ],\n defaultVariants: {\n variant: 'default',\n color: 'grey',\n active: false,\n },\n});\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"RuiCard.js","names":["_sfc_main"],"sources":["../../../src/components/cards/RuiCard.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { VueClassValue } from '@/types/class-value';\nimport { computed } from 'vue';\nimport RuiCardHeader from '@/components/cards/RuiCardHeader.vue';\nimport { useKeyboardScroll } from '@/composables/keyboard-scroll';\nimport { cn, tv } from '@/utils/tv';\n\nexport interface RuiCardClassNames {\n root?: VueClassValue;\n content?: VueClassValue;\n footer?: VueClassValue;\n image?: VueClassValue;\n}\n\nexport interface Props {\n dense?: boolean;\n divide?: boolean;\n variant?: 'flat' | 'outlined';\n rounded?: 'sm' | 'md' | 'lg';\n noPadding?: boolean;\n classNames?: RuiCardClassNames;\n}\n\ndefineOptions({\n name: 'RuiCard',\n inheritAttrs: false,\n});\n\nconst {\n divide = false,\n dense = false,\n variant: cardVariant = 'outlined',\n rounded = 'md',\n noPadding = false,\n classNames,\n} = defineProps<Props>();\n\nconst slots = defineSlots<{\n 'image'?: () => any;\n 'custom-header'?: () => any;\n 'prepend'?: () => any;\n 'header'?: () => any;\n 'subheader'?: () => any;\n 'default'?: () => any;\n 'footer'?: () => any;\n}>();\n\nconst card = tv({\n slots: {\n root: 'flex flex-col h-full w-full bg-rui-surface',\n image: 'overflow-hidden',\n content: 'text-sm/6 text-rui-text overflow-y-auto outline-hidden focus-visible:focus-ring focus-visible:-outline-offset-2',\n // a leading text button moves out by its side padding to align its label; unquoted selectors, quoted ones break consumer builds\n footer: [\n 'flex between:ml-2 between:mr-0 items-center justify-start mt-auto',\n '[&>[data-variant=text][data-size=xs]:first-child]:-ms-1',\n '[&>[data-variant=text][data-size=sm]:first-child]:-ms-1.5',\n '[&>[data-variant=text][data-size=md]:first-child]:-ms-2',\n '[&>[data-variant=text][data-size=lg]:first-child]:-ms-2.5',\n '[&>[data-variant=text][data-size$=xl]:first-child]:-ms-2.5',\n ],\n },\n variants: {\n variant: {\n flat: { root: '' },\n outlined: { root: 'border border-rui-divider' },\n },\n rounded: {\n sm: { root: 'rounded-rui-sm', image: 'rounded-t-rui-sm' },\n md: { root: 'rounded-rui-card', image: 'rounded-t-rui-card' },\n lg: { root: 'rounded-rui-lg', image: 'rounded-t-rui-lg' },\n },\n divide: {\n true: { root: 'between:border-t between:border-b-0 between:border-rui-divider' },\n },\n padding: {\n none: { content: 'p-0' },\n dense: { content: 'p-3' },\n normal: { content: 'p-4' },\n },\n dense: {\n // the footer keeps the content's side padding, so its buttons line up with the text above\n true: { footer: 'p-3 pt-1' },\n false: { footer: 'p-4 pt-2' },\n },\n },\n defaultVariants: { variant: 'outlined', rounded: 'md', padding: 'normal', dense: false },\n});\n\nconst content = useTemplateRef<HTMLDivElement>('content');\n// a fixed-height card scrolls its content, which keyboard users need to reach when it holds no controls\nconst contentTabindex = useKeyboardScroll(content);\n\nconst hasHeadContent = computed<boolean>(() => !!slots.header || !!slots.subheader);\n\nconst contentPadding = computed<'none' | 'dense' | 'normal'>(() => {\n if (noPadding)\n return 'none';\n return dense ? 'dense' : 'normal';\n});\n\nconst ui = computed<ReturnType<typeof card>>(() => card({ variant: cardVariant, rounded, divide, dense, padding: contentPadding.value }));\n</script>\n\n<template>\n <div\n :class=\"ui.root({ class: cn(classNames?.root ?? $attrs.class) })\"\n v-bind=\"{ ...$attrs, class: undefined }\"\n >\n <div\n v-if=\"slots.image\"\n data-id=\"card-image\"\n :class=\"ui.image({ class: cn(classNames?.image) })\"\n >\n <slot name=\"image\" />\n </div>\n <slot name=\"custom-header\">\n <RuiCardHeader\n v-if=\"hasHeadContent\"\n :dense=\"dense\"\n >\n <template\n v-if=\"slots.prepend\"\n #prepend\n >\n <slot name=\"prepend\" />\n </template>\n <template\n v-if=\"slots.header\"\n #header\n >\n <slot name=\"header\" />\n </template>\n <template\n v-if=\"slots.subheader\"\n #subheader\n >\n <slot name=\"subheader\" />\n </template>\n </RuiCardHeader>\n </slot>\n <div\n v-if=\"slots.default\"\n ref=\"content\"\n data-id=\"card-content\"\n :tabindex=\"contentTabindex\"\n :class=\"ui.content({ class: cn(classNames?.content) })\"\n >\n <slot />\n </div>\n <div\n v-if=\"slots.footer\"\n data-id=\"card-footer\"\n :class=\"ui.footer({ class: cn(classNames?.footer) })\"\n >\n <slot name=\"footer\" />\n </div>\n </div>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"RuiCard.js","names":["_sfc_main"],"sources":["../../../src/components/cards/RuiCard.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { VueClassValue } from '@/types/class-value';\nimport { computed } from 'vue';\nimport RuiCardHeader from '@/components/cards/RuiCardHeader.vue';\nimport { useKeyboardScroll } from '@/composables/keyboard-scroll';\nimport { cn, tv } from '@/utils/tv';\n\nexport interface RuiCardClassNames {\n root?: VueClassValue;\n content?: VueClassValue;\n footer?: VueClassValue;\n image?: VueClassValue;\n}\n\nexport interface Props {\n dense?: boolean;\n divide?: boolean;\n variant?: 'flat' | 'outlined';\n rounded?: 'sm' | 'md' | 'lg';\n noPadding?: boolean;\n /**\n * Drops the content's top padding when a header renders, so the header's bottom padding is the\n * only gap between them (16px, 12px when `dense`) instead of both paddings stacked. Ignored with\n * `divide`, which draws a border there.\n */\n tightHeaderGap?: boolean;\n classNames?: RuiCardClassNames;\n}\n\ndefineOptions({\n name: 'RuiCard',\n inheritAttrs: false,\n});\n\nconst {\n divide = false,\n dense = false,\n variant: cardVariant = 'outlined',\n rounded = 'md',\n noPadding = false,\n tightHeaderGap = false,\n classNames,\n} = defineProps<Props>();\n\nconst slots = defineSlots<{\n 'image'?: () => any;\n 'custom-header'?: () => any;\n 'prepend'?: () => any;\n 'header'?: () => any;\n 'subheader'?: () => any;\n 'default'?: () => any;\n 'footer'?: () => any;\n}>();\n\nconst card = tv({\n slots: {\n root: 'flex flex-col h-full w-full bg-rui-surface',\n image: 'overflow-hidden',\n content: 'text-sm/6 text-rui-text overflow-y-auto outline-hidden focus-visible:focus-ring focus-visible:-outline-offset-2',\n // a leading text button moves out by its side padding to align its label; unquoted selectors, quoted ones break consumer builds\n footer: [\n 'flex between:ml-2 between:mr-0 items-center justify-start mt-auto',\n '[&>[data-variant=text][data-size=xs]:first-child]:-ms-1',\n '[&>[data-variant=text][data-size=sm]:first-child]:-ms-1.5',\n '[&>[data-variant=text][data-size=md]:first-child]:-ms-2',\n '[&>[data-variant=text][data-size=lg]:first-child]:-ms-2.5',\n '[&>[data-variant=text][data-size$=xl]:first-child]:-ms-2.5',\n ],\n },\n variants: {\n variant: {\n flat: { root: '' },\n outlined: { root: 'border border-rui-divider' },\n },\n rounded: {\n sm: { root: 'rounded-rui-sm', image: 'rounded-t-rui-sm' },\n md: { root: 'rounded-rui-card', image: 'rounded-t-rui-card' },\n lg: { root: 'rounded-rui-lg', image: 'rounded-t-rui-lg' },\n },\n divide: {\n true: { root: 'between:border-t between:border-b-0 between:border-rui-divider' },\n },\n padding: {\n none: { content: 'p-0' },\n dense: { content: 'p-3' },\n normal: { content: 'p-4' },\n },\n dense: {\n // the footer keeps the content's side padding, so its buttons line up with the text above\n true: { footer: 'p-3 pt-1' },\n false: { footer: 'p-4 pt-2' },\n },\n underHeader: {\n true: { content: 'pt-0' },\n false: {},\n },\n },\n defaultVariants: { variant: 'outlined', rounded: 'md', padding: 'normal', dense: false, underHeader: false },\n});\n\nconst content = useTemplateRef<HTMLDivElement>('content');\n// a fixed-height card scrolls its content, which keyboard users need to reach when it holds no controls\nconst contentTabindex = useKeyboardScroll(content);\n\nconst hasHeadContent = computed<boolean>(() => !!slots.header || !!slots.subheader);\n\nconst contentPadding = computed<'none' | 'dense' | 'normal'>(() => {\n if (noPadding)\n return 'none';\n return dense ? 'dense' : 'normal';\n});\n\n// only under a header (built-in or `custom-header`), and not with `divide`, whose border needs space on both sides\nconst underHeader = computed<boolean>(() => tightHeaderGap && !divide && (get(hasHeadContent) || !!slots['custom-header']));\n\nconst ui = computed<ReturnType<typeof card>>(() => card({\n variant: cardVariant,\n rounded,\n divide,\n dense,\n padding: get(contentPadding),\n underHeader: get(underHeader),\n}));\n</script>\n\n<template>\n <div\n :class=\"ui.root({ class: cn(classNames?.root ?? $attrs.class) })\"\n v-bind=\"{ ...$attrs, class: undefined }\"\n >\n <div\n v-if=\"slots.image\"\n data-id=\"card-image\"\n :class=\"ui.image({ class: cn(classNames?.image) })\"\n >\n <slot name=\"image\" />\n </div>\n <slot name=\"custom-header\">\n <RuiCardHeader\n v-if=\"hasHeadContent\"\n :dense=\"dense\"\n >\n <template\n v-if=\"slots.prepend\"\n #prepend\n >\n <slot name=\"prepend\" />\n </template>\n <template\n v-if=\"slots.header\"\n #header\n >\n <slot name=\"header\" />\n </template>\n <template\n v-if=\"slots.subheader\"\n #subheader\n >\n <slot name=\"subheader\" />\n </template>\n </RuiCardHeader>\n </slot>\n <div\n v-if=\"slots.default\"\n ref=\"content\"\n data-id=\"card-content\"\n :tabindex=\"contentTabindex\"\n :class=\"ui.content({ class: cn(classNames?.content) })\"\n >\n <slot />\n </div>\n <div\n v-if=\"slots.footer\"\n data-id=\"card-footer\"\n :class=\"ui.footer({ class: cn(classNames?.footer) })\"\n >\n <slot name=\"footer\" />\n </div>\n </div>\n</template>\n"],"mappings":""}
@@ -11,6 +11,12 @@ export interface Props {
11
11
  variant?: 'flat' | 'outlined';
12
12
  rounded?: 'sm' | 'md' | 'lg';
13
13
  noPadding?: boolean;
14
+ /**
15
+ * Drops the content's top padding when a header renders, so the header's bottom padding is the
16
+ * only gap between them (16px, 12px when `dense`) instead of both paddings stacked. Ignored with
17
+ * `divide`, which draws a border there.
18
+ */
19
+ tightHeaderGap?: boolean;
14
20
  classNames?: RuiCardClassNames;
15
21
  }
16
22
  type __VLS_Slots = {
@@ -1,3 +1,4 @@
1
+ import { get } from "../../vendor/@vueuse/shared/dist/index.js";
1
2
  import { cn, tv } from "../../utils/tv.js";
2
3
  import RuiCardHeader_default from "./RuiCardHeader.js";
3
4
  import { useKeyboardScroll } from "../../composables/keyboard-scroll.js";
@@ -23,6 +24,10 @@ var RuiCard_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCo
23
24
  type: Boolean,
24
25
  default: false
25
26
  },
27
+ tightHeaderGap: {
28
+ type: Boolean,
29
+ default: false
30
+ },
26
31
  classNames: {}
27
32
  },
28
33
  setup(__props) {
@@ -69,13 +74,18 @@ var RuiCard_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCo
69
74
  dense: {
70
75
  true: { footer: "p-3 pt-1" },
71
76
  false: { footer: "p-4 pt-2" }
77
+ },
78
+ underHeader: {
79
+ true: { content: "pt-0" },
80
+ false: {}
72
81
  }
73
82
  },
74
83
  defaultVariants: {
75
84
  variant: "outlined",
76
85
  rounded: "md",
77
86
  padding: "normal",
78
- dense: false
87
+ dense: false,
88
+ underHeader: false
79
89
  }
80
90
  });
81
91
  const content = useTemplateRef("content");
@@ -85,12 +95,14 @@ var RuiCard_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCo
85
95
  if (__props.noPadding) return "none";
86
96
  return __props.dense ? "dense" : "normal";
87
97
  });
98
+ const underHeader = computed(() => __props.tightHeaderGap && !__props.divide && (get(hasHeadContent) || !!slots["custom-header"]));
88
99
  const ui = computed(() => card({
89
100
  variant: __props.variant,
90
101
  rounded: __props.rounded,
91
102
  divide: __props.divide,
92
103
  dense: __props.dense,
93
- padding: contentPadding.value
104
+ padding: get(contentPadding),
105
+ underHeader: get(underHeader)
94
106
  }));
95
107
  return (_ctx, _cache) => {
96
108
  return openBlock(), createElementBlock("div", mergeProps({ class: ui.value.root({ class: unref(cn)(__props.classNames?.root ?? _ctx.$attrs.class) }) }, {
@@ -1 +1 @@
1
- {"version":3,"file":"RuiCard.vue_vue_type_script_setup_true_lang.js","names":["$attrs","_useSlots","_openBlock","_createElementBlock","_mergeProps","_unref","_normalizeClass","_renderSlot","_createCommentVNode","_createBlock","RuiCardHeader","_createSlots","_withCtx"],"sources":["../../../src/components/cards/RuiCard.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { VueClassValue } from '@/types/class-value';\nimport { computed } from 'vue';\nimport RuiCardHeader from '@/components/cards/RuiCardHeader.vue';\nimport { useKeyboardScroll } from '@/composables/keyboard-scroll';\nimport { cn, tv } from '@/utils/tv';\n\nexport interface RuiCardClassNames {\n root?: VueClassValue;\n content?: VueClassValue;\n footer?: VueClassValue;\n image?: VueClassValue;\n}\n\nexport interface Props {\n dense?: boolean;\n divide?: boolean;\n variant?: 'flat' | 'outlined';\n rounded?: 'sm' | 'md' | 'lg';\n noPadding?: boolean;\n classNames?: RuiCardClassNames;\n}\n\ndefineOptions({\n name: 'RuiCard',\n inheritAttrs: false,\n});\n\nconst {\n divide = false,\n dense = false,\n variant: cardVariant = 'outlined',\n rounded = 'md',\n noPadding = false,\n classNames,\n} = defineProps<Props>();\n\nconst slots = defineSlots<{\n 'image'?: () => any;\n 'custom-header'?: () => any;\n 'prepend'?: () => any;\n 'header'?: () => any;\n 'subheader'?: () => any;\n 'default'?: () => any;\n 'footer'?: () => any;\n}>();\n\nconst card = tv({\n slots: {\n root: 'flex flex-col h-full w-full bg-rui-surface',\n image: 'overflow-hidden',\n content: 'text-sm/6 text-rui-text overflow-y-auto outline-hidden focus-visible:focus-ring focus-visible:-outline-offset-2',\n // a leading text button moves out by its side padding to align its label; unquoted selectors, quoted ones break consumer builds\n footer: [\n 'flex between:ml-2 between:mr-0 items-center justify-start mt-auto',\n '[&>[data-variant=text][data-size=xs]:first-child]:-ms-1',\n '[&>[data-variant=text][data-size=sm]:first-child]:-ms-1.5',\n '[&>[data-variant=text][data-size=md]:first-child]:-ms-2',\n '[&>[data-variant=text][data-size=lg]:first-child]:-ms-2.5',\n '[&>[data-variant=text][data-size$=xl]:first-child]:-ms-2.5',\n ],\n },\n variants: {\n variant: {\n flat: { root: '' },\n outlined: { root: 'border border-rui-divider' },\n },\n rounded: {\n sm: { root: 'rounded-rui-sm', image: 'rounded-t-rui-sm' },\n md: { root: 'rounded-rui-card', image: 'rounded-t-rui-card' },\n lg: { root: 'rounded-rui-lg', image: 'rounded-t-rui-lg' },\n },\n divide: {\n true: { root: 'between:border-t between:border-b-0 between:border-rui-divider' },\n },\n padding: {\n none: { content: 'p-0' },\n dense: { content: 'p-3' },\n normal: { content: 'p-4' },\n },\n dense: {\n // the footer keeps the content's side padding, so its buttons line up with the text above\n true: { footer: 'p-3 pt-1' },\n false: { footer: 'p-4 pt-2' },\n },\n },\n defaultVariants: { variant: 'outlined', rounded: 'md', padding: 'normal', dense: false },\n});\n\nconst content = useTemplateRef<HTMLDivElement>('content');\n// a fixed-height card scrolls its content, which keyboard users need to reach when it holds no controls\nconst contentTabindex = useKeyboardScroll(content);\n\nconst hasHeadContent = computed<boolean>(() => !!slots.header || !!slots.subheader);\n\nconst contentPadding = computed<'none' | 'dense' | 'normal'>(() => {\n if (noPadding)\n return 'none';\n return dense ? 'dense' : 'normal';\n});\n\nconst ui = computed<ReturnType<typeof card>>(() => card({ variant: cardVariant, rounded, divide, dense, padding: contentPadding.value }));\n</script>\n\n<template>\n <div\n :class=\"ui.root({ class: cn(classNames?.root ?? $attrs.class) })\"\n v-bind=\"{ ...$attrs, class: undefined }\"\n >\n <div\n v-if=\"slots.image\"\n data-id=\"card-image\"\n :class=\"ui.image({ class: cn(classNames?.image) })\"\n >\n <slot name=\"image\" />\n </div>\n <slot name=\"custom-header\">\n <RuiCardHeader\n v-if=\"hasHeadContent\"\n :dense=\"dense\"\n >\n <template\n v-if=\"slots.prepend\"\n #prepend\n >\n <slot name=\"prepend\" />\n </template>\n <template\n v-if=\"slots.header\"\n #header\n >\n <slot name=\"header\" />\n </template>\n <template\n v-if=\"slots.subheader\"\n #subheader\n >\n <slot name=\"subheader\" />\n </template>\n </RuiCardHeader>\n </slot>\n <div\n v-if=\"slots.default\"\n ref=\"content\"\n data-id=\"card-content\"\n :tabindex=\"contentTabindex\"\n :class=\"ui.content({ class: cn(classNames?.content) })\"\n >\n <slot />\n </div>\n <div\n v-if=\"slots.footer\"\n data-id=\"card-footer\"\n :class=\"ui.footer({ class: cn(classNames?.footer) })\"\n >\n <slot name=\"footer\" />\n </div>\n </div>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"RuiCard.vue_vue_type_script_setup_true_lang.js","names":["$attrs","_useSlots","_openBlock","_createElementBlock","_mergeProps","_unref","_normalizeClass","_renderSlot","_createCommentVNode","_createBlock","RuiCardHeader","_createSlots","_withCtx"],"sources":["../../../src/components/cards/RuiCard.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { VueClassValue } from '@/types/class-value';\nimport { computed } from 'vue';\nimport RuiCardHeader from '@/components/cards/RuiCardHeader.vue';\nimport { useKeyboardScroll } from '@/composables/keyboard-scroll';\nimport { cn, tv } from '@/utils/tv';\n\nexport interface RuiCardClassNames {\n root?: VueClassValue;\n content?: VueClassValue;\n footer?: VueClassValue;\n image?: VueClassValue;\n}\n\nexport interface Props {\n dense?: boolean;\n divide?: boolean;\n variant?: 'flat' | 'outlined';\n rounded?: 'sm' | 'md' | 'lg';\n noPadding?: boolean;\n /**\n * Drops the content's top padding when a header renders, so the header's bottom padding is the\n * only gap between them (16px, 12px when `dense`) instead of both paddings stacked. Ignored with\n * `divide`, which draws a border there.\n */\n tightHeaderGap?: boolean;\n classNames?: RuiCardClassNames;\n}\n\ndefineOptions({\n name: 'RuiCard',\n inheritAttrs: false,\n});\n\nconst {\n divide = false,\n dense = false,\n variant: cardVariant = 'outlined',\n rounded = 'md',\n noPadding = false,\n tightHeaderGap = false,\n classNames,\n} = defineProps<Props>();\n\nconst slots = defineSlots<{\n 'image'?: () => any;\n 'custom-header'?: () => any;\n 'prepend'?: () => any;\n 'header'?: () => any;\n 'subheader'?: () => any;\n 'default'?: () => any;\n 'footer'?: () => any;\n}>();\n\nconst card = tv({\n slots: {\n root: 'flex flex-col h-full w-full bg-rui-surface',\n image: 'overflow-hidden',\n content: 'text-sm/6 text-rui-text overflow-y-auto outline-hidden focus-visible:focus-ring focus-visible:-outline-offset-2',\n // a leading text button moves out by its side padding to align its label; unquoted selectors, quoted ones break consumer builds\n footer: [\n 'flex between:ml-2 between:mr-0 items-center justify-start mt-auto',\n '[&>[data-variant=text][data-size=xs]:first-child]:-ms-1',\n '[&>[data-variant=text][data-size=sm]:first-child]:-ms-1.5',\n '[&>[data-variant=text][data-size=md]:first-child]:-ms-2',\n '[&>[data-variant=text][data-size=lg]:first-child]:-ms-2.5',\n '[&>[data-variant=text][data-size$=xl]:first-child]:-ms-2.5',\n ],\n },\n variants: {\n variant: {\n flat: { root: '' },\n outlined: { root: 'border border-rui-divider' },\n },\n rounded: {\n sm: { root: 'rounded-rui-sm', image: 'rounded-t-rui-sm' },\n md: { root: 'rounded-rui-card', image: 'rounded-t-rui-card' },\n lg: { root: 'rounded-rui-lg', image: 'rounded-t-rui-lg' },\n },\n divide: {\n true: { root: 'between:border-t between:border-b-0 between:border-rui-divider' },\n },\n padding: {\n none: { content: 'p-0' },\n dense: { content: 'p-3' },\n normal: { content: 'p-4' },\n },\n dense: {\n // the footer keeps the content's side padding, so its buttons line up with the text above\n true: { footer: 'p-3 pt-1' },\n false: { footer: 'p-4 pt-2' },\n },\n underHeader: {\n true: { content: 'pt-0' },\n false: {},\n },\n },\n defaultVariants: { variant: 'outlined', rounded: 'md', padding: 'normal', dense: false, underHeader: false },\n});\n\nconst content = useTemplateRef<HTMLDivElement>('content');\n// a fixed-height card scrolls its content, which keyboard users need to reach when it holds no controls\nconst contentTabindex = useKeyboardScroll(content);\n\nconst hasHeadContent = computed<boolean>(() => !!slots.header || !!slots.subheader);\n\nconst contentPadding = computed<'none' | 'dense' | 'normal'>(() => {\n if (noPadding)\n return 'none';\n return dense ? 'dense' : 'normal';\n});\n\n// only under a header (built-in or `custom-header`), and not with `divide`, whose border needs space on both sides\nconst underHeader = computed<boolean>(() => tightHeaderGap && !divide && (get(hasHeadContent) || !!slots['custom-header']));\n\nconst ui = computed<ReturnType<typeof card>>(() => card({\n variant: cardVariant,\n rounded,\n divide,\n dense,\n padding: get(contentPadding),\n underHeader: get(underHeader),\n}));\n</script>\n\n<template>\n <div\n :class=\"ui.root({ class: cn(classNames?.root ?? $attrs.class) })\"\n v-bind=\"{ ...$attrs, class: undefined }\"\n >\n <div\n v-if=\"slots.image\"\n data-id=\"card-image\"\n :class=\"ui.image({ class: cn(classNames?.image) })\"\n >\n <slot name=\"image\" />\n </div>\n <slot name=\"custom-header\">\n <RuiCardHeader\n v-if=\"hasHeadContent\"\n :dense=\"dense\"\n >\n <template\n v-if=\"slots.prepend\"\n #prepend\n >\n <slot name=\"prepend\" />\n </template>\n <template\n v-if=\"slots.header\"\n #header\n >\n <slot name=\"header\" />\n </template>\n <template\n v-if=\"slots.subheader\"\n #subheader\n >\n <slot name=\"subheader\" />\n </template>\n </RuiCardHeader>\n </slot>\n <div\n v-if=\"slots.default\"\n ref=\"content\"\n data-id=\"card-content\"\n :tabindex=\"contentTabindex\"\n :class=\"ui.content({ class: cn(classNames?.content) })\"\n >\n <slot />\n </div>\n <div\n v-if=\"slots.footer\"\n data-id=\"card-footer\"\n :class=\"ui.footer({ class: cn(classNames?.footer) })\"\n >\n <slot name=\"footer\" />\n </div>\n </div>\n</template>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"RuiChip.js","names":["_sfc_main"],"sources":["../../../src/components/chips/RuiChip.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type { StyleValue } from 'vue';\nimport type { ContextColorsType } from '@/consts/colors';\nimport type { RuiIcons } from '@/icons';\nimport type { VueClassValue } from '@/types/class-value';\nimport { objectOmit } from '@vueuse/shared';\nimport { CHIP_CLOSE_ICON_SIZES, ChipSize, ChipVariant } from '@/components/chips/chip-props';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\nimport { cn, tv } from '@/utils/tv';\n\nexport interface RuiChipClassNames {\n root?: VueClassValue;\n content?: VueClassValue;\n}\n\nexport interface Props {\n tile?: boolean;\n clickable?: boolean;\n closeable?: boolean;\n disabled?: boolean;\n size?: ChipSize;\n variant?: ChipVariant;\n color?: 'grey' | ContextColorsType;\n closeIcon?: RuiIcons;\n /**\n * Takes the close button out of the tab order, for a chip inside a widget that removes chips from\n * the keyboard itself, as RuiAutoComplete does with Backspace. The button still takes clicks.\n */\n closeUnfocusable?: boolean;\n bgColor?: string;\n textColor?: string;\n classNames?: RuiChipClassNames;\n}\n\ndefineOptions({\n name: 'RuiChip',\n inheritAttrs: false,\n});\n\nconst {\n tile = false,\n size = ChipSize.md,\n color = 'grey',\n clickable = false,\n closeable = false,\n disabled = false,\n variant = ChipVariant.filled,\n closeIcon = 'lu-x',\n closeUnfocusable = false,\n bgColor = undefined,\n textColor = undefined,\n classNames,\n} = defineProps<Props>();\n\nconst emit = defineEmits<{\n 'click:close': [];\n 'click': [e: MouseEvent];\n}>();\n\nconst slots = defineSlots<{\n prepend?: () => any;\n default?: () => any;\n}>();\n\nconst root = useTemplateRef<HTMLDivElement>('root');\n\nconst chipStyles = tv({\n slots: {\n // min-h sets the height and items-center the rest, so a prefix or a border never adds to it\n root: 'inline-flex items-center justify-between px-2 transition duration-150 cursor-default outline-hidden max-w-full truncate',\n // the avatar's neutral pair, so initials stay readable on any chip color\n prepend: 'rounded-full flex items-center justify-center shrink-0 w-6 h-6 text-[0.625rem] font-semibold text-rui-neutral-700 bg-rui-neutral-200 dark:text-rui-neutral-200 dark:bg-rui-neutral-700 overflow-hidden',\n label: 'truncate px-2 text-[0.8125rem]/5',\n // a round hover fill marks the close icon as its own button\n close: 'rounded-full flex items-center p-0.5 inset-y-0 focus:outline-hidden transition-colors hover:bg-rui-pressed',\n closeIcon: 'opacity-60 hover:opacity-100 transition-opacity',\n },\n variants: {\n tile: {\n true: { root: 'rounded-rui-sm' },\n false: { root: 'rounded-full' },\n },\n size: {\n // 28px, to sit in a 44px table row; sm is 24px with 12px text, the smallest the library sets\n md: { root: 'min-h-7' },\n sm: {\n root: 'min-h-6',\n prepend: 'text-[0.5rem] p-[0.08rem] w-4 h-4',\n label: 'px-1.5 text-xs/4',\n close: 'p-px',\n },\n },\n // a leading circle sits as far from the start edge as from the top, like an avatar in a pill\n prepended: {\n true: { root: 'pl-0.5' },\n false: {},\n },\n closeable: {\n true: {},\n false: {},\n },\n disabled: {\n true: { root: '!text-rui-text-disabled cursor-default', close: 'cursor-default hover:bg-transparent dark:hover:bg-transparent' },\n false: {},\n },\n clickable: {\n true: { root: 'cursor-pointer' },\n false: { root: 'cursor-default', close: 'cursor-default' },\n },\n variant: {\n filled: {},\n outlined: {},\n tonal: {},\n },\n color: {\n grey: { root: 'text-rui-text' },\n primary: {},\n secondary: {},\n error: {},\n warning: {},\n info: {},\n success: {},\n },\n },\n compoundVariants: [\n // Interactive states (clickable + not disabled): a tint over any fill, which keeps the text color\n { clickable: true, disabled: false, class: { root: 'hover:state-layer active:state-layer-pressed focus-visible:focus-ring' } },\n\n // Grey filled: a solid step above the tonal tint\n { color: 'grey', variant: 'filled', class: { root: 'bg-rui-neutral-200 dark:bg-rui-neutral-700' } },\n\n // Outlined: the border is the text color at 40%, so it follows the brighter text tone in dark\n { variant: 'outlined', class: { root: 'border border-current/40 bg-transparent' } },\n\n // Context colors — filled bg\n { color: 'primary', variant: 'filled', class: { root: 'bg-rui-primary' } },\n { color: 'secondary', variant: 'filled', class: { root: 'bg-rui-secondary' } },\n // in dark a status color's `main` is a text tone, so the fill is its deep `darker`\n { color: 'error', variant: 'filled', class: { root: 'bg-rui-error dark:bg-rui-error-darker' } },\n { color: 'warning', variant: 'filled', class: { root: 'bg-rui-warning dark:bg-rui-warning-darker' } },\n { color: 'info', variant: 'filled', class: { root: 'bg-rui-info dark:bg-rui-info-darker' } },\n { color: 'success', variant: 'filled', class: { root: 'bg-rui-success dark:bg-rui-success-darker' } },\n\n // Context colors: outlined text\n { color: 'primary', variant: 'outlined', class: { root: 'text-rui-primary dark:text-rui-primary-lighter' } },\n { color: 'secondary', variant: 'outlined', class: { root: 'text-rui-secondary dark:text-rui-secondary-lighter' } },\n { color: 'error', variant: 'outlined', class: { root: 'text-rui-error dark:text-rui-error-lighter' } },\n { color: 'warning', variant: 'outlined', class: { root: 'text-rui-warning' } },\n { color: 'info', variant: 'outlined', class: { root: 'text-rui-info' } },\n { color: 'success', variant: 'outlined', class: { root: 'text-rui-success' } },\n\n // Tonal: a tint with the deeper tone as text, 4.5:1; primary and secondary sit near grey, so tint harder\n { color: 'grey', variant: 'tonal', class: { root: 'bg-rui-neutral-500/10 dark:bg-rui-neutral-400/10' } },\n { color: 'primary', variant: 'tonal', class: { root: 'bg-rui-primary/15 text-rui-primary-darker dark:bg-rui-primary/35 dark:text-rui-primary-lighter' } },\n { color: 'secondary', variant: 'tonal', class: { root: 'bg-rui-secondary/20 text-rui-secondary-darker dark:bg-rui-secondary/35 dark:text-rui-secondary-lighter' } },\n { color: 'error', variant: 'tonal', class: { root: 'bg-rui-error/10 text-rui-error-darker dark:bg-rui-error/20 dark:text-rui-error-lighter' } },\n { color: 'warning', variant: 'tonal', class: { root: 'bg-rui-warning/10 text-rui-warning-darker dark:bg-rui-warning/20 dark:text-rui-warning-lighter' } },\n { color: 'info', variant: 'tonal', class: { root: 'bg-rui-info/10 text-rui-info-darker dark:bg-rui-info/20 dark:text-rui-info-lighter' } },\n { color: 'success', variant: 'tonal', class: { root: 'bg-rui-success/10 text-rui-success-darker dark:bg-rui-success/20 dark:text-rui-success-lighter' } },\n\n // sm: a 16px circle in a 24px chip, 4px in from the start as from the top\n { size: 'sm', prepended: true, class: { root: 'pl-1' } },\n // in a tile chip the prefix follows the corners: the chip's 6px radius less the 2px inset\n { tile: true, class: { prepend: 'rounded-sm' } },\n // the close button's round hover area mirrors the prefix: as far from the end edge as from the top\n { closeable: true, class: { root: 'pr-1', label: 'pr-1' } },\n { closeable: true, size: 'sm', class: { root: 'pr-1', label: 'pr-0.5' } },\n\n // Disabled: a flat neutral chip in any color, like a disabled button\n { disabled: true, variant: ['filled', 'tonal'], class: { root: '!bg-rui-neutral-100 dark:!bg-rui-neutral-800' } },\n { disabled: true, variant: 'outlined', class: { root: '!border-rui-divider' } },\n ],\n compoundSlots: [\n // Every filled color takes light text, in both themes\n { slots: ['root'], color: ['primary', 'secondary', 'error', 'warning', 'info', 'success'], variant: 'filled', class: 'text-rui-dark-text' },\n ],\n defaultVariants: {\n tile: false,\n size: 'md',\n disabled: false,\n clickable: false,\n variant: 'filled',\n color: 'grey',\n },\n});\n\nconst ui = computed<ReturnType<typeof chipStyles>>(() => chipStyles({\n tile,\n size,\n color,\n variant,\n disabled,\n clickable,\n prepended: !!slots.prepend,\n closeable,\n}));\n\nconst style = computed<Partial<StyleValue>>(() => {\n const s: Partial<StyleValue> = {};\n if (bgColor)\n s.backgroundColor = bgColor;\n if (textColor)\n s.color = textColor;\n return s;\n});\n\nfunction click(e: MouseEvent): void {\n if (!clickable || disabled)\n return;\n\n emit('click', e);\n}\n\n/**\n * Enter and Space activate a clickable chip as they would a button, through a\n * real click so the handler still gets a `MouseEvent`.\n *\n * @param e - the key press on the chip\n */\nfunction onKeydown(e: KeyboardEvent): void {\n if (!clickable || disabled || e.target !== get(root))\n return;\n if (e.key !== 'Enter' && e.key !== ' ')\n return;\n\n e.preventDefault();\n get(root)?.click();\n}\n</script>\n\n<template>\n <div\n ref=\"root\"\n :class=\"ui.root({ class: cn(classNames?.root) })\"\n :style=\"style\"\n :data-variant=\"variant\"\n :data-color=\"color\"\n :data-disabled=\"disabled || undefined\"\n :role=\"clickable ? 'button' : undefined\"\n :tabindex=\"clickable && !disabled ? 0 : undefined\"\n :aria-disabled=\"clickable && disabled ? true : undefined\"\n v-bind=\"objectOmit($attrs, ['onClick'])\"\n @click=\"click($event)\"\n @keydown=\"onKeydown($event)\"\n >\n <div\n v-if=\"$slots.prepend\"\n :class=\"ui.prepend()\"\n >\n <slot name=\"prepend\" />\n </div>\n <span :class=\"ui.label({ class: cn(classNames?.content) })\">\n <slot />\n </span>\n <button\n v-if=\"closeable\"\n :class=\"ui.close()\"\n :disabled=\"disabled\"\n type=\"button\"\n aria-label=\"Remove\"\n :tabindex=\"closeUnfocusable ? -1 : undefined\"\n @click.stop=\"emit('click:close')\"\n >\n <RuiIcon\n :class=\"ui.closeIcon()\"\n :size=\"CHIP_CLOSE_ICON_SIZES[size]\"\n :name=\"closeIcon\"\n />\n </button>\n </div>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"RuiChip.js","names":["_sfc_main"],"sources":["../../../src/components/chips/RuiChip.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type { StyleValue } from 'vue';\nimport type { ContextColorsType } from '@/consts/colors';\nimport type { RuiIcons } from '@/icons';\nimport type { VueClassValue } from '@/types/class-value';\nimport { objectOmit } from '@vueuse/shared';\nimport { CHIP_CLOSE_ICON_SIZES, ChipSize, ChipVariant } from '@/components/chips/chip-props';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\nimport { cn, tv } from '@/utils/tv';\n\nexport interface RuiChipClassNames {\n root?: VueClassValue;\n content?: VueClassValue;\n}\n\nexport interface Props {\n tile?: boolean;\n clickable?: boolean;\n closeable?: boolean;\n disabled?: boolean;\n size?: ChipSize;\n variant?: ChipVariant;\n color?: 'grey' | ContextColorsType;\n closeIcon?: RuiIcons;\n /**\n * Takes the close button out of the tab order, for a chip inside a widget that removes chips from\n * the keyboard itself, as RuiAutoComplete does with Backspace. The button still takes clicks.\n */\n closeUnfocusable?: boolean;\n bgColor?: string;\n textColor?: string;\n classNames?: RuiChipClassNames;\n}\n\ndefineOptions({\n name: 'RuiChip',\n inheritAttrs: false,\n});\n\nconst {\n tile = false,\n size = ChipSize.md,\n color = 'grey',\n clickable = false,\n closeable = false,\n disabled = false,\n variant = ChipVariant.filled,\n closeIcon = 'lu-x',\n closeUnfocusable = false,\n bgColor = undefined,\n textColor = undefined,\n classNames,\n} = defineProps<Props>();\n\nconst emit = defineEmits<{\n 'click:close': [];\n 'click': [e: MouseEvent];\n}>();\n\nconst slots = defineSlots<{\n prepend?: () => any;\n default?: () => any;\n}>();\n\nconst root = useTemplateRef<HTMLDivElement>('root');\n\nconst chipStyles = tv({\n slots: {\n // min-h sets the height and items-center the rest, so a prefix or a border never adds to it\n root: 'inline-flex items-center justify-between px-2 transition duration-150 cursor-default outline-hidden max-w-full truncate',\n // the avatar's neutral pair, so initials stay readable on any chip color\n prepend: 'rounded-full flex items-center justify-center shrink-0 w-6 h-6 text-[0.625rem] font-semibold text-rui-neutral-700 bg-rui-neutral-200 dark:text-rui-neutral-200 dark:bg-rui-neutral-700 overflow-hidden',\n label: 'truncate px-2 text-[0.8125rem]/5',\n // a round hover fill marks the close icon as its own button\n close: 'rounded-full flex items-center p-0.5 inset-y-0 focus:outline-hidden transition-colors hover:bg-rui-pressed',\n closeIcon: 'opacity-60 hover:opacity-100 transition-opacity',\n },\n variants: {\n tile: {\n true: { root: 'rounded-rui-sm' },\n false: { root: 'rounded-full' },\n },\n size: {\n // 28px, to sit in a 44px table row; sm is 24px with 12px text\n md: { root: 'min-h-7' },\n sm: {\n root: 'min-h-6',\n prepend: 'text-[0.5rem] p-[0.08rem] w-4 h-4',\n label: 'px-1.5 text-xs/4',\n close: 'p-px',\n },\n // 20px for a count: 11px tabular figures keep a changing number from shifting the row\n xs: {\n root: 'min-h-5 px-1',\n prepend: 'text-[0.5rem] p-[0.08rem] w-4 h-4',\n label: 'px-1 text-[0.6875rem]/4 tabular-nums',\n close: 'p-px',\n },\n },\n // a leading circle sits as far from the start edge as from the top, like an avatar in a pill\n prepended: {\n true: { root: 'pl-0.5' },\n false: {},\n },\n closeable: {\n true: {},\n false: {},\n },\n disabled: {\n true: { root: '!text-rui-text-disabled cursor-default', close: 'cursor-default hover:bg-transparent dark:hover:bg-transparent' },\n false: {},\n },\n clickable: {\n true: { root: 'cursor-pointer' },\n false: { root: 'cursor-default', close: 'cursor-default' },\n },\n variant: {\n filled: {},\n outlined: {},\n tonal: {},\n },\n color: {\n grey: { root: 'text-rui-text' },\n primary: {},\n secondary: {},\n error: {},\n warning: {},\n info: {},\n success: {},\n },\n },\n compoundVariants: [\n // Interactive states (clickable + not disabled): a tint over any fill, which keeps the text color\n { clickable: true, disabled: false, class: { root: 'hover:state-layer active:state-layer-pressed focus-visible:focus-ring' } },\n\n // Grey filled: a solid step above the tonal tint\n { color: 'grey', variant: 'filled', class: { root: 'bg-rui-neutral-200 dark:bg-rui-neutral-700' } },\n\n // Outlined: the border is the text color at 40%, so it follows the brighter text tone in dark\n { variant: 'outlined', class: { root: 'border border-current/40 bg-transparent' } },\n\n // Context colors — filled bg\n { color: 'primary', variant: 'filled', class: { root: 'bg-rui-primary' } },\n { color: 'secondary', variant: 'filled', class: { root: 'bg-rui-secondary' } },\n // in dark a status color's `main` is a text tone, so the fill is its deep `darker`\n { color: 'error', variant: 'filled', class: { root: 'bg-rui-error dark:bg-rui-error-darker' } },\n { color: 'warning', variant: 'filled', class: { root: 'bg-rui-warning dark:bg-rui-warning-darker' } },\n { color: 'info', variant: 'filled', class: { root: 'bg-rui-info dark:bg-rui-info-darker' } },\n { color: 'success', variant: 'filled', class: { root: 'bg-rui-success dark:bg-rui-success-darker' } },\n\n // Context colors: outlined text\n { color: 'primary', variant: 'outlined', class: { root: 'text-rui-primary dark:text-rui-primary-lighter' } },\n { color: 'secondary', variant: 'outlined', class: { root: 'text-rui-secondary dark:text-rui-secondary-lighter' } },\n { color: 'error', variant: 'outlined', class: { root: 'text-rui-error dark:text-rui-error-lighter' } },\n { color: 'warning', variant: 'outlined', class: { root: 'text-rui-warning' } },\n { color: 'info', variant: 'outlined', class: { root: 'text-rui-info' } },\n { color: 'success', variant: 'outlined', class: { root: 'text-rui-success' } },\n\n // Tonal: a tint with the deeper tone as text, 4.5:1; primary and secondary sit near grey, so tint harder\n { color: 'grey', variant: 'tonal', class: { root: 'bg-rui-neutral-500/10 dark:bg-rui-neutral-400/10' } },\n { color: 'primary', variant: 'tonal', class: { root: 'bg-rui-primary/15 text-rui-primary-darker dark:bg-rui-primary/35 dark:text-rui-primary-lighter' } },\n { color: 'secondary', variant: 'tonal', class: { root: 'bg-rui-secondary/20 text-rui-secondary-darker dark:bg-rui-secondary/35 dark:text-rui-secondary-lighter' } },\n { color: 'error', variant: 'tonal', class: { root: 'bg-rui-error/10 text-rui-error-darker dark:bg-rui-error/20 dark:text-rui-error-lighter' } },\n { color: 'warning', variant: 'tonal', class: { root: 'bg-rui-warning/10 text-rui-warning-darker dark:bg-rui-warning/20 dark:text-rui-warning-lighter' } },\n { color: 'info', variant: 'tonal', class: { root: 'bg-rui-info/10 text-rui-info-darker dark:bg-rui-info/20 dark:text-rui-info-lighter' } },\n { color: 'success', variant: 'tonal', class: { root: 'bg-rui-success/10 text-rui-success-darker dark:bg-rui-success/20 dark:text-rui-success-lighter' } },\n\n // sm: a 16px circle in a 24px chip, 4px in from the start as from the top\n { size: 'sm', prepended: true, class: { root: 'pl-1' } },\n // in a tile chip the prefix follows the corners: the chip's 6px radius less the 2px inset\n { tile: true, class: { prepend: 'rounded-sm' } },\n // the close button's round hover area mirrors the prefix: as far from the end edge as from the top\n { closeable: true, class: { root: 'pr-1', label: 'pr-1' } },\n { closeable: true, size: 'sm', class: { root: 'pr-1', label: 'pr-0.5' } },\n // xs: the 12px close area sits 2px from the end edge, as the 16px prefix does from the start\n { closeable: true, size: 'xs', class: { root: 'pr-0.5', label: 'pr-0.5' } },\n\n // Disabled: a flat neutral chip in any color, like a disabled button\n { disabled: true, variant: ['filled', 'tonal'], class: { root: '!bg-rui-neutral-100 dark:!bg-rui-neutral-800' } },\n { disabled: true, variant: 'outlined', class: { root: '!border-rui-divider' } },\n ],\n compoundSlots: [\n // Every filled color takes light text, in both themes\n { slots: ['root'], color: ['primary', 'secondary', 'error', 'warning', 'info', 'success'], variant: 'filled', class: 'text-rui-dark-text' },\n ],\n defaultVariants: {\n tile: false,\n size: 'md',\n disabled: false,\n clickable: false,\n variant: 'filled',\n color: 'grey',\n },\n});\n\nconst ui = computed<ReturnType<typeof chipStyles>>(() => chipStyles({\n tile,\n size,\n color,\n variant,\n disabled,\n clickable,\n prepended: !!slots.prepend,\n closeable,\n}));\n\nconst style = computed<Partial<StyleValue>>(() => {\n const s: Partial<StyleValue> = {};\n if (bgColor)\n s.backgroundColor = bgColor;\n if (textColor)\n s.color = textColor;\n return s;\n});\n\nfunction click(e: MouseEvent): void {\n if (!clickable || disabled)\n return;\n\n emit('click', e);\n}\n\n/**\n * Enter and Space activate a clickable chip as they would a button, through a\n * real click so the handler still gets a `MouseEvent`.\n *\n * @param e - the key press on the chip\n */\nfunction onKeydown(e: KeyboardEvent): void {\n if (!clickable || disabled || e.target !== get(root))\n return;\n if (e.key !== 'Enter' && e.key !== ' ')\n return;\n\n e.preventDefault();\n get(root)?.click();\n}\n</script>\n\n<template>\n <div\n ref=\"root\"\n :class=\"ui.root({ class: cn(classNames?.root) })\"\n :style=\"style\"\n :data-variant=\"variant\"\n :data-color=\"color\"\n :data-disabled=\"disabled || undefined\"\n :role=\"clickable ? 'button' : undefined\"\n :tabindex=\"clickable && !disabled ? 0 : undefined\"\n :aria-disabled=\"clickable && disabled ? true : undefined\"\n v-bind=\"objectOmit($attrs, ['onClick'])\"\n @click=\"click($event)\"\n @keydown=\"onKeydown($event)\"\n >\n <div\n v-if=\"$slots.prepend\"\n :class=\"ui.prepend()\"\n >\n <slot name=\"prepend\" />\n </div>\n <span :class=\"ui.label({ class: cn(classNames?.content) })\">\n <slot />\n </span>\n <button\n v-if=\"closeable\"\n :class=\"ui.close()\"\n :disabled=\"disabled\"\n type=\"button\"\n aria-label=\"Remove\"\n :tabindex=\"closeUnfocusable ? -1 : undefined\"\n @click.stop=\"emit('click:close')\"\n >\n <RuiIcon\n :class=\"ui.closeIcon()\"\n :size=\"CHIP_CLOSE_ICON_SIZES[size]\"\n :name=\"closeIcon\"\n />\n </button>\n </div>\n</template>\n"],"mappings":""}
@@ -71,6 +71,12 @@ var RuiChip_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCo
71
71
  prepend: "text-[0.5rem] p-[0.08rem] w-4 h-4",
72
72
  label: "px-1.5 text-xs/4",
73
73
  close: "p-px"
74
+ },
75
+ xs: {
76
+ root: "min-h-5 px-1",
77
+ prepend: "text-[0.5rem] p-[0.08rem] w-4 h-4",
78
+ label: "px-1 text-[0.6875rem]/4 tabular-nums",
79
+ close: "p-px"
74
80
  }
75
81
  },
76
82
  prepended: {
@@ -244,6 +250,14 @@ var RuiChip_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCo
244
250
  label: "pr-0.5"
245
251
  }
246
252
  },
253
+ {
254
+ closeable: true,
255
+ size: "xs",
256
+ class: {
257
+ root: "pr-0.5",
258
+ label: "pr-0.5"
259
+ }
260
+ },
247
261
  {
248
262
  disabled: true,
249
263
  variant: ["filled", "tonal"],
@@ -1 +1 @@
1
- {"version":3,"file":"RuiChip.vue_vue_type_script_setup_true_lang.js","names":["$attrs","$slots","_useSlots","_openBlock","_createElementBlock","_mergeProps","_unref","_normalizeClass","_renderSlot","_createCommentVNode","_createElementVNode","_withModifiers","_createVNode","RuiIcon"],"sources":["../../../src/components/chips/RuiChip.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type { StyleValue } from 'vue';\nimport type { ContextColorsType } from '@/consts/colors';\nimport type { RuiIcons } from '@/icons';\nimport type { VueClassValue } from '@/types/class-value';\nimport { objectOmit } from '@vueuse/shared';\nimport { CHIP_CLOSE_ICON_SIZES, ChipSize, ChipVariant } from '@/components/chips/chip-props';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\nimport { cn, tv } from '@/utils/tv';\n\nexport interface RuiChipClassNames {\n root?: VueClassValue;\n content?: VueClassValue;\n}\n\nexport interface Props {\n tile?: boolean;\n clickable?: boolean;\n closeable?: boolean;\n disabled?: boolean;\n size?: ChipSize;\n variant?: ChipVariant;\n color?: 'grey' | ContextColorsType;\n closeIcon?: RuiIcons;\n /**\n * Takes the close button out of the tab order, for a chip inside a widget that removes chips from\n * the keyboard itself, as RuiAutoComplete does with Backspace. The button still takes clicks.\n */\n closeUnfocusable?: boolean;\n bgColor?: string;\n textColor?: string;\n classNames?: RuiChipClassNames;\n}\n\ndefineOptions({\n name: 'RuiChip',\n inheritAttrs: false,\n});\n\nconst {\n tile = false,\n size = ChipSize.md,\n color = 'grey',\n clickable = false,\n closeable = false,\n disabled = false,\n variant = ChipVariant.filled,\n closeIcon = 'lu-x',\n closeUnfocusable = false,\n bgColor = undefined,\n textColor = undefined,\n classNames,\n} = defineProps<Props>();\n\nconst emit = defineEmits<{\n 'click:close': [];\n 'click': [e: MouseEvent];\n}>();\n\nconst slots = defineSlots<{\n prepend?: () => any;\n default?: () => any;\n}>();\n\nconst root = useTemplateRef<HTMLDivElement>('root');\n\nconst chipStyles = tv({\n slots: {\n // min-h sets the height and items-center the rest, so a prefix or a border never adds to it\n root: 'inline-flex items-center justify-between px-2 transition duration-150 cursor-default outline-hidden max-w-full truncate',\n // the avatar's neutral pair, so initials stay readable on any chip color\n prepend: 'rounded-full flex items-center justify-center shrink-0 w-6 h-6 text-[0.625rem] font-semibold text-rui-neutral-700 bg-rui-neutral-200 dark:text-rui-neutral-200 dark:bg-rui-neutral-700 overflow-hidden',\n label: 'truncate px-2 text-[0.8125rem]/5',\n // a round hover fill marks the close icon as its own button\n close: 'rounded-full flex items-center p-0.5 inset-y-0 focus:outline-hidden transition-colors hover:bg-rui-pressed',\n closeIcon: 'opacity-60 hover:opacity-100 transition-opacity',\n },\n variants: {\n tile: {\n true: { root: 'rounded-rui-sm' },\n false: { root: 'rounded-full' },\n },\n size: {\n // 28px, to sit in a 44px table row; sm is 24px with 12px text, the smallest the library sets\n md: { root: 'min-h-7' },\n sm: {\n root: 'min-h-6',\n prepend: 'text-[0.5rem] p-[0.08rem] w-4 h-4',\n label: 'px-1.5 text-xs/4',\n close: 'p-px',\n },\n },\n // a leading circle sits as far from the start edge as from the top, like an avatar in a pill\n prepended: {\n true: { root: 'pl-0.5' },\n false: {},\n },\n closeable: {\n true: {},\n false: {},\n },\n disabled: {\n true: { root: '!text-rui-text-disabled cursor-default', close: 'cursor-default hover:bg-transparent dark:hover:bg-transparent' },\n false: {},\n },\n clickable: {\n true: { root: 'cursor-pointer' },\n false: { root: 'cursor-default', close: 'cursor-default' },\n },\n variant: {\n filled: {},\n outlined: {},\n tonal: {},\n },\n color: {\n grey: { root: 'text-rui-text' },\n primary: {},\n secondary: {},\n error: {},\n warning: {},\n info: {},\n success: {},\n },\n },\n compoundVariants: [\n // Interactive states (clickable + not disabled): a tint over any fill, which keeps the text color\n { clickable: true, disabled: false, class: { root: 'hover:state-layer active:state-layer-pressed focus-visible:focus-ring' } },\n\n // Grey filled: a solid step above the tonal tint\n { color: 'grey', variant: 'filled', class: { root: 'bg-rui-neutral-200 dark:bg-rui-neutral-700' } },\n\n // Outlined: the border is the text color at 40%, so it follows the brighter text tone in dark\n { variant: 'outlined', class: { root: 'border border-current/40 bg-transparent' } },\n\n // Context colors — filled bg\n { color: 'primary', variant: 'filled', class: { root: 'bg-rui-primary' } },\n { color: 'secondary', variant: 'filled', class: { root: 'bg-rui-secondary' } },\n // in dark a status color's `main` is a text tone, so the fill is its deep `darker`\n { color: 'error', variant: 'filled', class: { root: 'bg-rui-error dark:bg-rui-error-darker' } },\n { color: 'warning', variant: 'filled', class: { root: 'bg-rui-warning dark:bg-rui-warning-darker' } },\n { color: 'info', variant: 'filled', class: { root: 'bg-rui-info dark:bg-rui-info-darker' } },\n { color: 'success', variant: 'filled', class: { root: 'bg-rui-success dark:bg-rui-success-darker' } },\n\n // Context colors: outlined text\n { color: 'primary', variant: 'outlined', class: { root: 'text-rui-primary dark:text-rui-primary-lighter' } },\n { color: 'secondary', variant: 'outlined', class: { root: 'text-rui-secondary dark:text-rui-secondary-lighter' } },\n { color: 'error', variant: 'outlined', class: { root: 'text-rui-error dark:text-rui-error-lighter' } },\n { color: 'warning', variant: 'outlined', class: { root: 'text-rui-warning' } },\n { color: 'info', variant: 'outlined', class: { root: 'text-rui-info' } },\n { color: 'success', variant: 'outlined', class: { root: 'text-rui-success' } },\n\n // Tonal: a tint with the deeper tone as text, 4.5:1; primary and secondary sit near grey, so tint harder\n { color: 'grey', variant: 'tonal', class: { root: 'bg-rui-neutral-500/10 dark:bg-rui-neutral-400/10' } },\n { color: 'primary', variant: 'tonal', class: { root: 'bg-rui-primary/15 text-rui-primary-darker dark:bg-rui-primary/35 dark:text-rui-primary-lighter' } },\n { color: 'secondary', variant: 'tonal', class: { root: 'bg-rui-secondary/20 text-rui-secondary-darker dark:bg-rui-secondary/35 dark:text-rui-secondary-lighter' } },\n { color: 'error', variant: 'tonal', class: { root: 'bg-rui-error/10 text-rui-error-darker dark:bg-rui-error/20 dark:text-rui-error-lighter' } },\n { color: 'warning', variant: 'tonal', class: { root: 'bg-rui-warning/10 text-rui-warning-darker dark:bg-rui-warning/20 dark:text-rui-warning-lighter' } },\n { color: 'info', variant: 'tonal', class: { root: 'bg-rui-info/10 text-rui-info-darker dark:bg-rui-info/20 dark:text-rui-info-lighter' } },\n { color: 'success', variant: 'tonal', class: { root: 'bg-rui-success/10 text-rui-success-darker dark:bg-rui-success/20 dark:text-rui-success-lighter' } },\n\n // sm: a 16px circle in a 24px chip, 4px in from the start as from the top\n { size: 'sm', prepended: true, class: { root: 'pl-1' } },\n // in a tile chip the prefix follows the corners: the chip's 6px radius less the 2px inset\n { tile: true, class: { prepend: 'rounded-sm' } },\n // the close button's round hover area mirrors the prefix: as far from the end edge as from the top\n { closeable: true, class: { root: 'pr-1', label: 'pr-1' } },\n { closeable: true, size: 'sm', class: { root: 'pr-1', label: 'pr-0.5' } },\n\n // Disabled: a flat neutral chip in any color, like a disabled button\n { disabled: true, variant: ['filled', 'tonal'], class: { root: '!bg-rui-neutral-100 dark:!bg-rui-neutral-800' } },\n { disabled: true, variant: 'outlined', class: { root: '!border-rui-divider' } },\n ],\n compoundSlots: [\n // Every filled color takes light text, in both themes\n { slots: ['root'], color: ['primary', 'secondary', 'error', 'warning', 'info', 'success'], variant: 'filled', class: 'text-rui-dark-text' },\n ],\n defaultVariants: {\n tile: false,\n size: 'md',\n disabled: false,\n clickable: false,\n variant: 'filled',\n color: 'grey',\n },\n});\n\nconst ui = computed<ReturnType<typeof chipStyles>>(() => chipStyles({\n tile,\n size,\n color,\n variant,\n disabled,\n clickable,\n prepended: !!slots.prepend,\n closeable,\n}));\n\nconst style = computed<Partial<StyleValue>>(() => {\n const s: Partial<StyleValue> = {};\n if (bgColor)\n s.backgroundColor = bgColor;\n if (textColor)\n s.color = textColor;\n return s;\n});\n\nfunction click(e: MouseEvent): void {\n if (!clickable || disabled)\n return;\n\n emit('click', e);\n}\n\n/**\n * Enter and Space activate a clickable chip as they would a button, through a\n * real click so the handler still gets a `MouseEvent`.\n *\n * @param e - the key press on the chip\n */\nfunction onKeydown(e: KeyboardEvent): void {\n if (!clickable || disabled || e.target !== get(root))\n return;\n if (e.key !== 'Enter' && e.key !== ' ')\n return;\n\n e.preventDefault();\n get(root)?.click();\n}\n</script>\n\n<template>\n <div\n ref=\"root\"\n :class=\"ui.root({ class: cn(classNames?.root) })\"\n :style=\"style\"\n :data-variant=\"variant\"\n :data-color=\"color\"\n :data-disabled=\"disabled || undefined\"\n :role=\"clickable ? 'button' : undefined\"\n :tabindex=\"clickable && !disabled ? 0 : undefined\"\n :aria-disabled=\"clickable && disabled ? true : undefined\"\n v-bind=\"objectOmit($attrs, ['onClick'])\"\n @click=\"click($event)\"\n @keydown=\"onKeydown($event)\"\n >\n <div\n v-if=\"$slots.prepend\"\n :class=\"ui.prepend()\"\n >\n <slot name=\"prepend\" />\n </div>\n <span :class=\"ui.label({ class: cn(classNames?.content) })\">\n <slot />\n </span>\n <button\n v-if=\"closeable\"\n :class=\"ui.close()\"\n :disabled=\"disabled\"\n type=\"button\"\n aria-label=\"Remove\"\n :tabindex=\"closeUnfocusable ? -1 : undefined\"\n @click.stop=\"emit('click:close')\"\n >\n <RuiIcon\n :class=\"ui.closeIcon()\"\n :size=\"CHIP_CLOSE_ICON_SIZES[size]\"\n :name=\"closeIcon\"\n />\n </button>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsDA,MAAM,OAAO;EAKb,MAAM,QAAQE,SAAA;EAKd,MAAM,OAAO,eAA+B,MAAM;EAElD,MAAM,aAAa,GAAG;GACpB,OAAO;IAEL,MAAM;IAEN,SAAS;IACT,OAAO;IAEP,OAAO;IACP,WAAW;GACb;GACA,UAAU;IACR,MAAM;KACJ,MAAM,EAAE,MAAM,iBAAiB;KAC/B,OAAO,EAAE,MAAM,eAAe;IAChC;IACA,MAAM;KAEJ,IAAI,EAAE,MAAM,UAAU;KACtB,IAAI;MACF,MAAM;MACN,SAAS;MACT,OAAO;MACP,OAAO;KACT;IACF;IAEA,WAAW;KACT,MAAM,EAAE,MAAM,SAAS;KACvB,OAAO,CAAC;IACV;IACA,WAAW;KACT,MAAM,CAAC;KACP,OAAO,CAAC;IACV;IACA,UAAU;KACR,MAAM;MAAE,MAAM;MAA0C,OAAO;KAAgE;KAC/H,OAAO,CAAC;IACV;IACA,WAAW;KACT,MAAM,EAAE,MAAM,iBAAiB;KAC/B,OAAO;MAAE,MAAM;MAAkB,OAAO;KAAiB;IAC3D;IACA,SAAS;KACP,QAAQ,CAAC;KACT,UAAU,CAAC;KACX,OAAO,CAAC;IACV;IACA,OAAO;KACL,MAAM,EAAE,MAAM,gBAAgB;KAC9B,SAAS,CAAC;KACV,WAAW,CAAC;KACZ,OAAO,CAAC;KACR,SAAS,CAAC;KACV,MAAM,CAAC;KACP,SAAS,CAAC;IACZ;GACF;GACA,kBAAkB;IAEhB;KAAE,WAAW;KAAM,UAAU;KAAO,OAAO,EAAE,MAAM,wEAAwE;IAAE;IAG7H;KAAE,OAAO;KAAQ,SAAS;KAAU,OAAO,EAAE,MAAM,6CAA6C;IAAE;IAGlG;KAAE,SAAS;KAAY,OAAO,EAAE,MAAM,0CAA0C;IAAE;IAGlF;KAAE,OAAO;KAAW,SAAS;KAAU,OAAO,EAAE,MAAM,iBAAiB;IAAE;IACzE;KAAE,OAAO;KAAa,SAAS;KAAU,OAAO,EAAE,MAAM,mBAAmB;IAAE;IAE7E;KAAE,OAAO;KAAS,SAAS;KAAU,OAAO,EAAE,MAAM,wCAAwC;IAAE;IAC9F;KAAE,OAAO;KAAW,SAAS;KAAU,OAAO,EAAE,MAAM,4CAA4C;IAAE;IACpG;KAAE,OAAO;KAAQ,SAAS;KAAU,OAAO,EAAE,MAAM,sCAAsC;IAAE;IAC3F;KAAE,OAAO;KAAW,SAAS;KAAU,OAAO,EAAE,MAAM,4CAA4C;IAAE;IAGpG;KAAE,OAAO;KAAW,SAAS;KAAY,OAAO,EAAE,MAAM,iDAAiD;IAAE;IAC3G;KAAE,OAAO;KAAa,SAAS;KAAY,OAAO,EAAE,MAAM,qDAAqD;IAAE;IACjH;KAAE,OAAO;KAAS,SAAS;KAAY,OAAO,EAAE,MAAM,6CAA6C;IAAE;IACrG;KAAE,OAAO;KAAW,SAAS;KAAY,OAAO,EAAE,MAAM,mBAAmB;IAAE;IAC7E;KAAE,OAAO;KAAQ,SAAS;KAAY,OAAO,EAAE,MAAM,gBAAgB;IAAE;IACvE;KAAE,OAAO;KAAW,SAAS;KAAY,OAAO,EAAE,MAAM,mBAAmB;IAAE;IAG7E;KAAE,OAAO;KAAQ,SAAS;KAAS,OAAO,EAAE,MAAM,mDAAmD;IAAE;IACvG;KAAE,OAAO;KAAW,SAAS;KAAS,OAAO,EAAE,MAAM,iGAAiG;IAAE;IACxJ;KAAE,OAAO;KAAa,SAAS;KAAS,OAAO,EAAE,MAAM,yGAAyG;IAAE;IAClK;KAAE,OAAO;KAAS,SAAS;KAAS,OAAO,EAAE,MAAM,yFAAyF;IAAE;IAC9I;KAAE,OAAO;KAAW,SAAS;KAAS,OAAO,EAAE,MAAM,iGAAiG;IAAE;IACxJ;KAAE,OAAO;KAAQ,SAAS;KAAS,OAAO,EAAE,MAAM,qFAAqF;IAAE;IACzI;KAAE,OAAO;KAAW,SAAS;KAAS,OAAO,EAAE,MAAM,iGAAiG;IAAE;IAGxJ;KAAE,MAAM;KAAM,WAAW;KAAM,OAAO,EAAE,MAAM,OAAO;IAAE;IAEvD;KAAE,MAAM;KAAM,OAAO,EAAE,SAAS,aAAa;IAAE;IAE/C;KAAE,WAAW;KAAM,OAAO;MAAE,MAAM;MAAQ,OAAO;KAAO;IAAE;IAC1D;KAAE,WAAW;KAAM,MAAM;KAAM,OAAO;MAAE,MAAM;MAAQ,OAAO;KAAS;IAAE;IAGxE;KAAE,UAAU;KAAM,SAAS,CAAC,UAAU,OAAO;KAAG,OAAO,EAAE,MAAM,+CAA+C;IAAE;IAChH;KAAE,UAAU;KAAM,SAAS;KAAY,OAAO,EAAE,MAAM,sBAAsB;IAAE;GAChF;GACA,eAAe,CAEb;IAAE,OAAO,CAAC,MAAM;IAAG,OAAO;KAAC;KAAW;KAAa;KAAS;KAAW;KAAQ;IAAS;IAAG,SAAS;IAAU,OAAO;GAAqB,CAC5I;GACA,iBAAiB;IACf,MAAM;IACN,MAAM;IACN,UAAU;IACV,WAAW;IACX,SAAS;IACT,OAAO;GACT;EACF,CAAC;EAED,MAAM,KAAK,eAA8C,WAAW;GAClE,MAAG,QAAA;GACH,MAAG,QAAA;GACH,OAAI,QAAA;GACJ,SAAM,QAAA;GACN,UAAO,QAAA;GACP,WAAQ,QAAA;GACR,WAAW,CAAC,CAAC,MAAM;GACnB,WAAQ,QAAA;EACV,CAAC,CAAC;EAEF,MAAM,QAAQ,eAAoC;GAChD,MAAM,IAAyB,CAAC;GAChC,IAAI,QAAA,SACF,EAAE,kBAAkB,QAAA;GACtB,IAAI,QAAA,WACF,EAAE,QAAQ,QAAA;GACZ,OAAO;EACT,CAAC;EAED,SAAS,MAAM,GAAqB;GAClC,IAAI,CAAC,QAAA,aAAa,QAAA,UAChB;GAEF,KAAK,SAAS,CAAC;EACjB;;;;;;;EAQA,SAAS,UAAU,GAAwB;GACzC,IAAI,CAAC,QAAA,aAAa,QAAA,YAAY,EAAE,WAAW,IAAI,IAAI,GACjD;GACF,IAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,KACjC;GAEF,EAAE,eAAe;GACjB,IAAI,IAAI,CAAC,EAAE,MAAM;EACnB;;GAIE,OAAAC,UAAA,GAAAC,mBAsCM,OAtCNC,WAsCM;IArCA,SAAA;IAAJ,KAAI;IACH,OAAOC,MAAA,EAAA,CAAE,CAAC,KAAI,EAAA,OAAUA,MAAA,EAAA,CAAE,CAAC,QAAA,YAAY,IAAI,EAAA,CAAA;IAC3C,OAAOA,MAAA,KAAA;IACP,gBAAc,QAAA;IACd,cAAY,QAAA;IACZ,iBAAe,QAAA,YAAY,KAAA;IAC3B,MAAM,QAAA,YAAS,WAAc,KAAA;IAC7B,UAAU,QAAA,aAAS,CAAK,QAAA,WAAQ,IAAO,KAAA;IACvC,iBAAe,QAAA,aAAa,QAAA,WAAQ,OAAU,KAAA;GACvC,GAAAA,MAAA,UAAA,CAAU,CAACN,KAAAA,QAAM,CAAA,SAAA,CAAA,GAAA;IACxB,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,MAAM,MAAM;IACnB,WAAO,OAAA,OAAA,OAAA,MAAA,WAAE,UAAU,MAAM;;IAGlBC,KAAAA,OAAO,WADfE,UAAA,GAAAC,mBAKM,OAAA;;KAHH,OAAKG,eAAED,MAAA,EAAA,CAAE,CAAC,QAAO,CAAA;IAElBE,GAAAA,CAAAA,WAAuB,KAAA,QAAA,SAAA,CAAA,GAAA,CAAA,KAAA,mBAAA,IAAA,IAAA;IAEzBE,mBAEO,QAAA,EAFA,OAAKH,eAAED,MAAA,EAAA,CAAE,CAAC,MAAK,EAAA,OAAUA,MAAA,EAAA,CAAE,CAAC,QAAA,YAAY,OAAO,EAAA,CAAA,CAAA,EAAA,GAAA,CACpDE,WAAQ,KAAA,QAAA,SAAA,CAAA,GAAA,CAAA;IAGF,QAAA,aADRL,UAAA,GAAAC,mBAcS,UAAA;;KAZN,OAAKG,eAAED,MAAA,EAAA,CAAE,CAAC,MAAK,CAAA;KACf,UAAU,QAAA;KACX,MAAK;KACL,cAAW;KACV,UAAU,QAAA,mBAAgB,KAAQ,KAAA;KAClC,SAAK,OAAA,OAAA,OAAA,KAAAK,eAAA,WAAO,KAAI,aAAA,GAAA,CAAA,MAAA,CAAA;IAEjBC,GAAAA,CAAAA,YAIEC,iBAAA;KAHC,OAAKN,eAAED,MAAA,EAAA,CAAE,CAAC,UAAS,CAAA;KACnB,MAAMA,MAAA,qBAAA,CAAqB,CAAC,QAAA;KAC5B,MAAM,QAAA"}
1
+ {"version":3,"file":"RuiChip.vue_vue_type_script_setup_true_lang.js","names":["$attrs","$slots","_useSlots","_openBlock","_createElementBlock","_mergeProps","_unref","_normalizeClass","_renderSlot","_createCommentVNode","_createElementVNode","_withModifiers","_createVNode","RuiIcon"],"sources":["../../../src/components/chips/RuiChip.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type { StyleValue } from 'vue';\nimport type { ContextColorsType } from '@/consts/colors';\nimport type { RuiIcons } from '@/icons';\nimport type { VueClassValue } from '@/types/class-value';\nimport { objectOmit } from '@vueuse/shared';\nimport { CHIP_CLOSE_ICON_SIZES, ChipSize, ChipVariant } from '@/components/chips/chip-props';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\nimport { cn, tv } from '@/utils/tv';\n\nexport interface RuiChipClassNames {\n root?: VueClassValue;\n content?: VueClassValue;\n}\n\nexport interface Props {\n tile?: boolean;\n clickable?: boolean;\n closeable?: boolean;\n disabled?: boolean;\n size?: ChipSize;\n variant?: ChipVariant;\n color?: 'grey' | ContextColorsType;\n closeIcon?: RuiIcons;\n /**\n * Takes the close button out of the tab order, for a chip inside a widget that removes chips from\n * the keyboard itself, as RuiAutoComplete does with Backspace. The button still takes clicks.\n */\n closeUnfocusable?: boolean;\n bgColor?: string;\n textColor?: string;\n classNames?: RuiChipClassNames;\n}\n\ndefineOptions({\n name: 'RuiChip',\n inheritAttrs: false,\n});\n\nconst {\n tile = false,\n size = ChipSize.md,\n color = 'grey',\n clickable = false,\n closeable = false,\n disabled = false,\n variant = ChipVariant.filled,\n closeIcon = 'lu-x',\n closeUnfocusable = false,\n bgColor = undefined,\n textColor = undefined,\n classNames,\n} = defineProps<Props>();\n\nconst emit = defineEmits<{\n 'click:close': [];\n 'click': [e: MouseEvent];\n}>();\n\nconst slots = defineSlots<{\n prepend?: () => any;\n default?: () => any;\n}>();\n\nconst root = useTemplateRef<HTMLDivElement>('root');\n\nconst chipStyles = tv({\n slots: {\n // min-h sets the height and items-center the rest, so a prefix or a border never adds to it\n root: 'inline-flex items-center justify-between px-2 transition duration-150 cursor-default outline-hidden max-w-full truncate',\n // the avatar's neutral pair, so initials stay readable on any chip color\n prepend: 'rounded-full flex items-center justify-center shrink-0 w-6 h-6 text-[0.625rem] font-semibold text-rui-neutral-700 bg-rui-neutral-200 dark:text-rui-neutral-200 dark:bg-rui-neutral-700 overflow-hidden',\n label: 'truncate px-2 text-[0.8125rem]/5',\n // a round hover fill marks the close icon as its own button\n close: 'rounded-full flex items-center p-0.5 inset-y-0 focus:outline-hidden transition-colors hover:bg-rui-pressed',\n closeIcon: 'opacity-60 hover:opacity-100 transition-opacity',\n },\n variants: {\n tile: {\n true: { root: 'rounded-rui-sm' },\n false: { root: 'rounded-full' },\n },\n size: {\n // 28px, to sit in a 44px table row; sm is 24px with 12px text\n md: { root: 'min-h-7' },\n sm: {\n root: 'min-h-6',\n prepend: 'text-[0.5rem] p-[0.08rem] w-4 h-4',\n label: 'px-1.5 text-xs/4',\n close: 'p-px',\n },\n // 20px for a count: 11px tabular figures keep a changing number from shifting the row\n xs: {\n root: 'min-h-5 px-1',\n prepend: 'text-[0.5rem] p-[0.08rem] w-4 h-4',\n label: 'px-1 text-[0.6875rem]/4 tabular-nums',\n close: 'p-px',\n },\n },\n // a leading circle sits as far from the start edge as from the top, like an avatar in a pill\n prepended: {\n true: { root: 'pl-0.5' },\n false: {},\n },\n closeable: {\n true: {},\n false: {},\n },\n disabled: {\n true: { root: '!text-rui-text-disabled cursor-default', close: 'cursor-default hover:bg-transparent dark:hover:bg-transparent' },\n false: {},\n },\n clickable: {\n true: { root: 'cursor-pointer' },\n false: { root: 'cursor-default', close: 'cursor-default' },\n },\n variant: {\n filled: {},\n outlined: {},\n tonal: {},\n },\n color: {\n grey: { root: 'text-rui-text' },\n primary: {},\n secondary: {},\n error: {},\n warning: {},\n info: {},\n success: {},\n },\n },\n compoundVariants: [\n // Interactive states (clickable + not disabled): a tint over any fill, which keeps the text color\n { clickable: true, disabled: false, class: { root: 'hover:state-layer active:state-layer-pressed focus-visible:focus-ring' } },\n\n // Grey filled: a solid step above the tonal tint\n { color: 'grey', variant: 'filled', class: { root: 'bg-rui-neutral-200 dark:bg-rui-neutral-700' } },\n\n // Outlined: the border is the text color at 40%, so it follows the brighter text tone in dark\n { variant: 'outlined', class: { root: 'border border-current/40 bg-transparent' } },\n\n // Context colors — filled bg\n { color: 'primary', variant: 'filled', class: { root: 'bg-rui-primary' } },\n { color: 'secondary', variant: 'filled', class: { root: 'bg-rui-secondary' } },\n // in dark a status color's `main` is a text tone, so the fill is its deep `darker`\n { color: 'error', variant: 'filled', class: { root: 'bg-rui-error dark:bg-rui-error-darker' } },\n { color: 'warning', variant: 'filled', class: { root: 'bg-rui-warning dark:bg-rui-warning-darker' } },\n { color: 'info', variant: 'filled', class: { root: 'bg-rui-info dark:bg-rui-info-darker' } },\n { color: 'success', variant: 'filled', class: { root: 'bg-rui-success dark:bg-rui-success-darker' } },\n\n // Context colors: outlined text\n { color: 'primary', variant: 'outlined', class: { root: 'text-rui-primary dark:text-rui-primary-lighter' } },\n { color: 'secondary', variant: 'outlined', class: { root: 'text-rui-secondary dark:text-rui-secondary-lighter' } },\n { color: 'error', variant: 'outlined', class: { root: 'text-rui-error dark:text-rui-error-lighter' } },\n { color: 'warning', variant: 'outlined', class: { root: 'text-rui-warning' } },\n { color: 'info', variant: 'outlined', class: { root: 'text-rui-info' } },\n { color: 'success', variant: 'outlined', class: { root: 'text-rui-success' } },\n\n // Tonal: a tint with the deeper tone as text, 4.5:1; primary and secondary sit near grey, so tint harder\n { color: 'grey', variant: 'tonal', class: { root: 'bg-rui-neutral-500/10 dark:bg-rui-neutral-400/10' } },\n { color: 'primary', variant: 'tonal', class: { root: 'bg-rui-primary/15 text-rui-primary-darker dark:bg-rui-primary/35 dark:text-rui-primary-lighter' } },\n { color: 'secondary', variant: 'tonal', class: { root: 'bg-rui-secondary/20 text-rui-secondary-darker dark:bg-rui-secondary/35 dark:text-rui-secondary-lighter' } },\n { color: 'error', variant: 'tonal', class: { root: 'bg-rui-error/10 text-rui-error-darker dark:bg-rui-error/20 dark:text-rui-error-lighter' } },\n { color: 'warning', variant: 'tonal', class: { root: 'bg-rui-warning/10 text-rui-warning-darker dark:bg-rui-warning/20 dark:text-rui-warning-lighter' } },\n { color: 'info', variant: 'tonal', class: { root: 'bg-rui-info/10 text-rui-info-darker dark:bg-rui-info/20 dark:text-rui-info-lighter' } },\n { color: 'success', variant: 'tonal', class: { root: 'bg-rui-success/10 text-rui-success-darker dark:bg-rui-success/20 dark:text-rui-success-lighter' } },\n\n // sm: a 16px circle in a 24px chip, 4px in from the start as from the top\n { size: 'sm', prepended: true, class: { root: 'pl-1' } },\n // in a tile chip the prefix follows the corners: the chip's 6px radius less the 2px inset\n { tile: true, class: { prepend: 'rounded-sm' } },\n // the close button's round hover area mirrors the prefix: as far from the end edge as from the top\n { closeable: true, class: { root: 'pr-1', label: 'pr-1' } },\n { closeable: true, size: 'sm', class: { root: 'pr-1', label: 'pr-0.5' } },\n // xs: the 12px close area sits 2px from the end edge, as the 16px prefix does from the start\n { closeable: true, size: 'xs', class: { root: 'pr-0.5', label: 'pr-0.5' } },\n\n // Disabled: a flat neutral chip in any color, like a disabled button\n { disabled: true, variant: ['filled', 'tonal'], class: { root: '!bg-rui-neutral-100 dark:!bg-rui-neutral-800' } },\n { disabled: true, variant: 'outlined', class: { root: '!border-rui-divider' } },\n ],\n compoundSlots: [\n // Every filled color takes light text, in both themes\n { slots: ['root'], color: ['primary', 'secondary', 'error', 'warning', 'info', 'success'], variant: 'filled', class: 'text-rui-dark-text' },\n ],\n defaultVariants: {\n tile: false,\n size: 'md',\n disabled: false,\n clickable: false,\n variant: 'filled',\n color: 'grey',\n },\n});\n\nconst ui = computed<ReturnType<typeof chipStyles>>(() => chipStyles({\n tile,\n size,\n color,\n variant,\n disabled,\n clickable,\n prepended: !!slots.prepend,\n closeable,\n}));\n\nconst style = computed<Partial<StyleValue>>(() => {\n const s: Partial<StyleValue> = {};\n if (bgColor)\n s.backgroundColor = bgColor;\n if (textColor)\n s.color = textColor;\n return s;\n});\n\nfunction click(e: MouseEvent): void {\n if (!clickable || disabled)\n return;\n\n emit('click', e);\n}\n\n/**\n * Enter and Space activate a clickable chip as they would a button, through a\n * real click so the handler still gets a `MouseEvent`.\n *\n * @param e - the key press on the chip\n */\nfunction onKeydown(e: KeyboardEvent): void {\n if (!clickable || disabled || e.target !== get(root))\n return;\n if (e.key !== 'Enter' && e.key !== ' ')\n return;\n\n e.preventDefault();\n get(root)?.click();\n}\n</script>\n\n<template>\n <div\n ref=\"root\"\n :class=\"ui.root({ class: cn(classNames?.root) })\"\n :style=\"style\"\n :data-variant=\"variant\"\n :data-color=\"color\"\n :data-disabled=\"disabled || undefined\"\n :role=\"clickable ? 'button' : undefined\"\n :tabindex=\"clickable && !disabled ? 0 : undefined\"\n :aria-disabled=\"clickable && disabled ? true : undefined\"\n v-bind=\"objectOmit($attrs, ['onClick'])\"\n @click=\"click($event)\"\n @keydown=\"onKeydown($event)\"\n >\n <div\n v-if=\"$slots.prepend\"\n :class=\"ui.prepend()\"\n >\n <slot name=\"prepend\" />\n </div>\n <span :class=\"ui.label({ class: cn(classNames?.content) })\">\n <slot />\n </span>\n <button\n v-if=\"closeable\"\n :class=\"ui.close()\"\n :disabled=\"disabled\"\n type=\"button\"\n aria-label=\"Remove\"\n :tabindex=\"closeUnfocusable ? -1 : undefined\"\n @click.stop=\"emit('click:close')\"\n >\n <RuiIcon\n :class=\"ui.closeIcon()\"\n :size=\"CHIP_CLOSE_ICON_SIZES[size]\"\n :name=\"closeIcon\"\n />\n </button>\n </div>\n</template>\n"],"mappings":"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"}
@@ -1,4 +1,6 @@
1
1
  export declare const ChipSize: {
2
+ /** 20px with 11px tabular figures, for counts beside a heading or in a row */
3
+ readonly xs: "xs";
2
4
  readonly sm: "sm";
3
5
  readonly md: "md";
4
6
  };
@@ -1,5 +1,7 @@
1
1
  //#region src/components/chips/chip-props.ts
2
2
  var ChipSize = {
3
+ /** 20px with 11px tabular figures, for counts beside a heading or in a row */
4
+ xs: "xs",
3
5
  sm: "sm",
4
6
  md: "md"
5
7
  };
@@ -10,6 +12,7 @@ var ChipVariant = {
10
12
  tonal: "tonal"
11
13
  };
12
14
  var CHIP_CLOSE_ICON_SIZES = {
15
+ xs: 10,
13
16
  sm: 12,
14
17
  md: 14
15
18
  };
@@ -1 +1 @@
1
- {"version":3,"file":"chip-props.js","names":[],"sources":["../../../src/components/chips/chip-props.ts"],"sourcesContent":["export const ChipSize = {\n sm: 'sm',\n md: 'md',\n} as const;\n\nexport type ChipSize = (typeof ChipSize)[keyof typeof ChipSize];\n\nexport const ChipVariant = {\n filled: 'filled',\n outlined: 'outlined',\n /** A soft tint of the color with deeper text, for status tags in dense views */\n tonal: 'tonal',\n} as const;\n\nexport type ChipVariant = (typeof ChipVariant)[keyof typeof ChipVariant];\n\nexport const CHIP_CLOSE_ICON_SIZES: Record<ChipSize, number> = {\n sm: 12,\n md: 14,\n};\n"],"mappings":";AAAA,IAAa,WAAW;CACtB,IAAI;CACJ,IAAI;AACN;AAIA,IAAa,cAAc;CACzB,QAAQ;CACR,UAAU;;CAEV,OAAO;AACT;AAIA,IAAa,wBAAkD;CAC7D,IAAI;CACJ,IAAI;AACN"}
1
+ {"version":3,"file":"chip-props.js","names":[],"sources":["../../../src/components/chips/chip-props.ts"],"sourcesContent":["export const ChipSize = {\n /** 20px with 11px tabular figures, for counts beside a heading or in a row */\n xs: 'xs',\n sm: 'sm',\n md: 'md',\n} as const;\n\nexport type ChipSize = (typeof ChipSize)[keyof typeof ChipSize];\n\nexport const ChipVariant = {\n filled: 'filled',\n outlined: 'outlined',\n /** A soft tint of the color with deeper text, for status tags in dense views */\n tonal: 'tonal',\n} as const;\n\nexport type ChipVariant = (typeof ChipVariant)[keyof typeof ChipVariant];\n\nexport const CHIP_CLOSE_ICON_SIZES: Record<ChipSize, number> = {\n xs: 10,\n sm: 12,\n md: 14,\n};\n"],"mappings":";AAAA,IAAa,WAAW;;CAEtB,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;AAIA,IAAa,cAAc;CACzB,QAAQ;CACR,UAAU;;CAEV,OAAO;AACT;AAIA,IAAa,wBAAkD;CAC7D,IAAI;CACJ,IAAI;CACJ,IAAI;AACN"}
@@ -1 +1 @@
1
- {"version":3,"file":"RuiColorInput.js","names":["_sfc_main"],"sources":["../../../src/components/color-picker/RuiColorInput.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type { Color, ColorFormat } from './utils';\nimport { clamp } from '@vueuse/shared';\nimport tinycolor from 'tinycolor2';\nimport RuiTextField from '@/components/forms/text-field/RuiTextField.vue';\nimport RuiTab from '@/components/tabs/tab/RuiTab.vue';\nimport RuiTabs from '@/components/tabs/tabs/RuiTabs.vue';\n\ndefineOptions({\n name: 'RuiColorInput',\n inheritAttrs: false,\n});\n\nconst modelValue = defineModel<Color>({ required: true });\n\nconst MAX_RGB = 255;\nconst VALID_HEX_LENGTHS = [3, 4, 6];\nconst DEFAULT_HEX = '000000';\nconst RGB_CHANNELS = ['Red', 'Green', 'Blue'];\n\nconst inputType = ref<ColorFormat>('hex');\nconst state = reactive({\n color: get(modelValue),\n hex: get(modelValue).hex,\n rgb: get(modelValue).rgb,\n});\n\nfunction applyRgbValue(value: string, key: number): void {\n if (!state.rgb || !state.color)\n return;\n\n const clamped = clamp(Number(value), 0, MAX_RGB);\n state.rgb[key] = clamped;\n const [r, g, b] = state.rgb;\n state.color.hex = tinycolor({ r, g, b }).toHex();\n}\n\nconst onBlurChange = useDebounceFn((format: ColorFormat, event: Event, key?: number) => {\n if (!state.color)\n return;\n\n const target = event.target;\n if (!(target instanceof HTMLInputElement))\n return;\n\n const value = target.value;\n if (format === 'hex') {\n const hex = value.replace('#', '');\n if (tinycolor(hex).isValid() && VALID_HEX_LENGTHS.includes(hex.length))\n state.color.hex = hex;\n else state.color.hex = DEFAULT_HEX;\n }\n else if (key !== undefined) {\n applyRgbValue(value, key);\n }\n\n set(modelValue, state.color);\n}, 100);\n\nconst onInputChange = useDebounceFn((format: ColorFormat, value: string, key?: number) => {\n if (!value)\n return;\n\n if (format === 'hex') {\n const hex = value.replace('#', '');\n if (tinycolor(hex).isValid() && state.color && hex.length === 6)\n state.color.hex = hex;\n }\n else if (key !== undefined) {\n applyRgbValue(value, key);\n }\n\n set(modelValue, state.color);\n}, 300);\n\nfunction onInputTypeChange(value: string | number): void {\n if (value === 'hex' || value === 'rgb')\n set(inputType, value);\n}\n\nwatch(\n () => {\n const color = get(modelValue);\n return [color.hex, ...color.rgb] as const;\n },\n () => {\n const color = get(modelValue);\n state.color = color;\n state.hex = color.hex;\n state.rgb = color.rgb;\n },\n);\n</script>\n\n<template>\n <div\n data-id=\"color-input\"\n class=\"flex flex-col gap-2 w-full\"\n v-bind=\"$attrs\"\n >\n <!-- the format is a choice between two views of one value, which is what a segmented control is for -->\n <RuiTabs\n :model-value=\"inputType\"\n variant=\"segmented\"\n grow\n data-id=\"color-format\"\n @update:model-value=\"onInputTypeChange($event)\"\n >\n <RuiTab value=\"hex\">\n Hex\n </RuiTab>\n <RuiTab value=\"rgb\">\n RGB\n </RuiTab>\n </RuiTabs>\n <RuiTextField\n v-if=\"inputType === 'hex'\"\n v-model=\"state.hex\"\n class=\"w-full [&_input]:uppercase\"\n maxlength=\"6\"\n color=\"primary\"\n aria-label=\"Hex color\"\n dense\n hide-details\n @update:model-value=\"onInputChange(inputType, $event)\"\n @blur=\"onBlurChange(inputType, $event)\"\n >\n <template #prepend>\n <span class=\"text-rui-text-secondary\">#</span>\n </template>\n </RuiTextField>\n <div\n v-else\n class=\"flex gap-1\"\n >\n <RuiTextField\n v-for=\"(v, i) in state.rgb\"\n :key=\"i\"\n :model-value=\"v.toString()\"\n class=\"[&_input]:text-center w-full\"\n maxlength=\"3\"\n color=\"primary\"\n :aria-label=\"RGB_CHANNELS[i]\"\n dense\n hide-details\n @update:model-value=\"onInputChange(inputType, $event, i)\"\n @blur=\"onBlurChange(inputType, $event, i)\"\n />\n </div>\n </div>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"RuiColorInput.js","names":["_sfc_main"],"sources":["../../../src/components/color-picker/RuiColorInput.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type { Color, ColorFormat } from './utils';\nimport { clamp } from '@vueuse/shared';\nimport tinycolor from 'tinycolor2';\nimport RuiTextField from '@/components/forms/text-field/RuiTextField.vue';\nimport RuiTab from '@/components/tabs/tab/RuiTab.vue';\nimport RuiTabs from '@/components/tabs/tabs/RuiTabs.vue';\n\ndefineOptions({\n name: 'RuiColorInput',\n inheritAttrs: false,\n});\n\nconst modelValue = defineModel<Color>({ required: true });\n\nconst MAX_RGB = 255;\nconst VALID_HEX_LENGTHS = [3, 4, 6];\nconst DEFAULT_HEX = '000000';\nconst RGB_CHANNELS = ['Red', 'Green', 'Blue'];\n\nconst inputType = ref<ColorFormat>('hex');\nconst state = reactive({\n color: get(modelValue),\n hex: get(modelValue).hex,\n rgb: get(modelValue).rgb,\n});\n\nfunction applyRgbValue(value: string, key: number): void {\n if (!state.rgb || !state.color)\n return;\n\n const clamped = clamp(Number(value), 0, MAX_RGB);\n state.rgb[key] = clamped;\n const [r, g, b] = state.rgb;\n state.color.hex = tinycolor({ r, g, b }).toHex();\n}\n\nconst onBlurChange = useDebounceFn((format: ColorFormat, event: Event, key?: number) => {\n if (!state.color)\n return;\n\n const target = event.target;\n if (!(target instanceof HTMLInputElement))\n return;\n\n const value = target.value;\n if (format === 'hex') {\n const hex = value.replace('#', '');\n if (tinycolor(hex).isValid() && VALID_HEX_LENGTHS.includes(hex.length))\n state.color.hex = hex;\n else state.color.hex = DEFAULT_HEX;\n }\n else if (key !== undefined) {\n applyRgbValue(value, key);\n }\n\n set(modelValue, state.color);\n}, 100);\n\nconst onInputChange = useDebounceFn((format: ColorFormat, value: string, key?: number) => {\n if (!value)\n return;\n\n if (format === 'hex') {\n const hex = value.replace('#', '');\n if (tinycolor(hex).isValid() && state.color && hex.length === 6)\n state.color.hex = hex;\n }\n else if (key !== undefined) {\n applyRgbValue(value, key);\n }\n\n set(modelValue, state.color);\n}, 300);\n\nfunction onInputTypeChange(value: string | number): void {\n if (value === 'hex' || value === 'rgb')\n set(inputType, value);\n}\n\nwatch(\n () => {\n const color = get(modelValue);\n return [color.hex, ...color.rgb] as const;\n },\n () => {\n const color = get(modelValue);\n state.color = color;\n state.hex = color.hex;\n state.rgb = color.rgb;\n },\n);\n</script>\n\n<template>\n <div\n data-id=\"color-input\"\n class=\"flex flex-col gap-2 w-full\"\n v-bind=\"$attrs\"\n >\n <!-- the format is a choice between two views of one value, which is what a segmented control is for -->\n <RuiTabs\n :model-value=\"inputType\"\n variant=\"segmented\"\n grow\n data-id=\"color-format\"\n @update:model-value=\"onInputTypeChange($event)\"\n >\n <RuiTab value=\"hex\">\n Hex\n </RuiTab>\n <RuiTab value=\"rgb\">\n RGB\n </RuiTab>\n </RuiTabs>\n <RuiTextField\n v-if=\"inputType === 'hex'\"\n v-model=\"state.hex\"\n class=\"w-full [&_input]:uppercase\"\n maxlength=\"6\"\n color=\"primary\"\n aria-label=\"Hex color\"\n dense\n details=\"hidden\"\n @update:model-value=\"onInputChange(inputType, $event)\"\n @blur=\"onBlurChange(inputType, $event)\"\n >\n <template #prepend>\n <span class=\"text-rui-text-secondary\">#</span>\n </template>\n </RuiTextField>\n <div\n v-else\n class=\"flex gap-1\"\n >\n <RuiTextField\n v-for=\"(v, i) in state.rgb\"\n :key=\"i\"\n :model-value=\"v.toString()\"\n class=\"[&_input]:text-center w-full\"\n maxlength=\"3\"\n color=\"primary\"\n :aria-label=\"RGB_CHANNELS[i]\"\n dense\n details=\"hidden\"\n @update:model-value=\"onInputChange(inputType, $event, i)\"\n @blur=\"onBlurChange(inputType, $event, i)\"\n />\n </div>\n </div>\n</template>\n"],"mappings":""}
@@ -109,7 +109,7 @@ var RuiColorInput_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ de
109
109
  color: "primary",
110
110
  "aria-label": "Hex color",
111
111
  dense: "",
112
- "hide-details": "",
112
+ details: "hidden",
113
113
  onBlur: _cache[3] || (_cache[3] = ($event) => unref(onBlurChange)(unref(inputType), $event))
114
114
  }, {
115
115
  prepend: withCtx(() => [..._cache[6] || (_cache[6] = [createElementVNode("span", { class: "text-rui-text-secondary" }, "#", -1)])]),
@@ -123,7 +123,7 @@ var RuiColorInput_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ de
123
123
  color: "primary",
124
124
  "aria-label": RGB_CHANNELS[i],
125
125
  dense: "",
126
- "hide-details": "",
126
+ details: "hidden",
127
127
  "onUpdate:modelValue": ($event) => unref(onInputChange)(unref(inputType), $event, i),
128
128
  onBlur: ($event) => unref(onBlurChange)(unref(inputType), $event, i)
129
129
  }, null, 8, [
@@ -1 +1 @@
1
- {"version":3,"file":"RuiColorInput.vue_vue_type_script_setup_true_lang.js","names":["$attrs","_useModel","_openBlock","_createElementBlock","_mergeProps","_createVNode","RuiTabs","_unref","_withCtx","RuiTab","_createTextVNode","_createBlock","RuiTextField","_createElementVNode","_Fragment","_renderList"],"sources":["../../../src/components/color-picker/RuiColorInput.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type { Color, ColorFormat } from './utils';\nimport { clamp } from '@vueuse/shared';\nimport tinycolor from 'tinycolor2';\nimport RuiTextField from '@/components/forms/text-field/RuiTextField.vue';\nimport RuiTab from '@/components/tabs/tab/RuiTab.vue';\nimport RuiTabs from '@/components/tabs/tabs/RuiTabs.vue';\n\ndefineOptions({\n name: 'RuiColorInput',\n inheritAttrs: false,\n});\n\nconst modelValue = defineModel<Color>({ required: true });\n\nconst MAX_RGB = 255;\nconst VALID_HEX_LENGTHS = [3, 4, 6];\nconst DEFAULT_HEX = '000000';\nconst RGB_CHANNELS = ['Red', 'Green', 'Blue'];\n\nconst inputType = ref<ColorFormat>('hex');\nconst state = reactive({\n color: get(modelValue),\n hex: get(modelValue).hex,\n rgb: get(modelValue).rgb,\n});\n\nfunction applyRgbValue(value: string, key: number): void {\n if (!state.rgb || !state.color)\n return;\n\n const clamped = clamp(Number(value), 0, MAX_RGB);\n state.rgb[key] = clamped;\n const [r, g, b] = state.rgb;\n state.color.hex = tinycolor({ r, g, b }).toHex();\n}\n\nconst onBlurChange = useDebounceFn((format: ColorFormat, event: Event, key?: number) => {\n if (!state.color)\n return;\n\n const target = event.target;\n if (!(target instanceof HTMLInputElement))\n return;\n\n const value = target.value;\n if (format === 'hex') {\n const hex = value.replace('#', '');\n if (tinycolor(hex).isValid() && VALID_HEX_LENGTHS.includes(hex.length))\n state.color.hex = hex;\n else state.color.hex = DEFAULT_HEX;\n }\n else if (key !== undefined) {\n applyRgbValue(value, key);\n }\n\n set(modelValue, state.color);\n}, 100);\n\nconst onInputChange = useDebounceFn((format: ColorFormat, value: string, key?: number) => {\n if (!value)\n return;\n\n if (format === 'hex') {\n const hex = value.replace('#', '');\n if (tinycolor(hex).isValid() && state.color && hex.length === 6)\n state.color.hex = hex;\n }\n else if (key !== undefined) {\n applyRgbValue(value, key);\n }\n\n set(modelValue, state.color);\n}, 300);\n\nfunction onInputTypeChange(value: string | number): void {\n if (value === 'hex' || value === 'rgb')\n set(inputType, value);\n}\n\nwatch(\n () => {\n const color = get(modelValue);\n return [color.hex, ...color.rgb] as const;\n },\n () => {\n const color = get(modelValue);\n state.color = color;\n state.hex = color.hex;\n state.rgb = color.rgb;\n },\n);\n</script>\n\n<template>\n <div\n data-id=\"color-input\"\n class=\"flex flex-col gap-2 w-full\"\n v-bind=\"$attrs\"\n >\n <!-- the format is a choice between two views of one value, which is what a segmented control is for -->\n <RuiTabs\n :model-value=\"inputType\"\n variant=\"segmented\"\n grow\n data-id=\"color-format\"\n @update:model-value=\"onInputTypeChange($event)\"\n >\n <RuiTab value=\"hex\">\n Hex\n </RuiTab>\n <RuiTab value=\"rgb\">\n RGB\n </RuiTab>\n </RuiTabs>\n <RuiTextField\n v-if=\"inputType === 'hex'\"\n v-model=\"state.hex\"\n class=\"w-full [&_input]:uppercase\"\n maxlength=\"6\"\n color=\"primary\"\n aria-label=\"Hex color\"\n dense\n hide-details\n @update:model-value=\"onInputChange(inputType, $event)\"\n @blur=\"onBlurChange(inputType, $event)\"\n >\n <template #prepend>\n <span class=\"text-rui-text-secondary\">#</span>\n </template>\n </RuiTextField>\n <div\n v-else\n class=\"flex gap-1\"\n >\n <RuiTextField\n v-for=\"(v, i) in state.rgb\"\n :key=\"i\"\n :model-value=\"v.toString()\"\n class=\"[&_input]:text-center w-full\"\n maxlength=\"3\"\n color=\"primary\"\n :aria-label=\"RGB_CHANNELS[i]\"\n dense\n hide-details\n @update:model-value=\"onInputChange(inputType, $event, i)\"\n @blur=\"onBlurChange(inputType, $event, i)\"\n />\n </div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;AAeA,IAAM,UAAU;AAEhB,IAAM,cAAc;;;;;;;;;;;EAJpB,MAAM,aAAaC,SAAkB,SAAA,YAAmB;EAGxD,MAAM,oBAAoB;GAAC;GAAG;GAAG;EAAC;EAElC,MAAM,eAAe;GAAC;GAAO;GAAS;EAAM;EAE5C,MAAM,YAAY,IAAiB,KAAK;EACxC,MAAM,QAAQ,SAAS;GACrB,OAAO,IAAI,UAAU;GACrB,KAAK,IAAI,UAAU,CAAC,CAAC;GACrB,KAAK,IAAI,UAAU,CAAC,CAAC;EACvB,CAAC;EAED,SAAS,cAAc,OAAe,KAAmB;GACvD,IAAI,CAAC,MAAM,OAAO,CAAC,MAAM,OACvB;GAEF,MAAM,UAAU,MAAM,OAAO,KAAK,GAAG,GAAG,OAAO;GAC/C,MAAM,IAAI,OAAO;GACjB,MAAM,CAAC,GAAG,GAAG,KAAK,MAAM;GACxB,MAAM,MAAM,MAAM,UAAU;IAAE;IAAG;IAAG;GAAE,CAAC,CAAC,CAAC,MAAM;EACjD;EAEA,MAAM,eAAe,eAAe,QAAqB,OAAc,QAAiB;GACtF,IAAI,CAAC,MAAM,OACT;GAEF,MAAM,SAAS,MAAM;GACrB,IAAI,EAAE,kBAAkB,mBACtB;GAEF,MAAM,QAAQ,OAAO;GACrB,IAAI,WAAW,OAAO;IACpB,MAAM,MAAM,MAAM,QAAQ,KAAK,EAAE;IACjC,IAAI,UAAU,GAAG,CAAC,CAAC,QAAQ,KAAK,kBAAkB,SAAS,IAAI,MAAM,GACnE,MAAM,MAAM,MAAM;SACf,MAAM,MAAM,MAAM;GACzB,OACK,IAAI,QAAQ,KAAA,GACf,cAAc,OAAO,GAAG;GAG1B,IAAI,YAAY,MAAM,KAAK;EAC7B,GAAG,GAAG;EAEN,MAAM,gBAAgB,eAAe,QAAqB,OAAe,QAAiB;GACxF,IAAI,CAAC,OACH;GAEF,IAAI,WAAW,OAAO;IACpB,MAAM,MAAM,MAAM,QAAQ,KAAK,EAAE;IACjC,IAAI,UAAU,GAAG,CAAC,CAAC,QAAQ,KAAK,MAAM,SAAS,IAAI,WAAW,GAC5D,MAAM,MAAM,MAAM;GACtB,OACK,IAAI,QAAQ,KAAA,GACf,cAAc,OAAO,GAAG;GAG1B,IAAI,YAAY,MAAM,KAAK;EAC7B,GAAG,GAAG;EAEN,SAAS,kBAAkB,OAA8B;GACvD,IAAI,UAAU,SAAS,UAAU,OAC/B,IAAI,WAAW,KAAK;EACxB;EAEA,YACQ;GACJ,MAAM,QAAQ,IAAI,UAAU;GAC5B,OAAO,CAAC,MAAM,KAAK,GAAG,MAAM,GAAG;EACjC,SACM;GACJ,MAAM,QAAQ,IAAI,UAAU;GAC5B,MAAM,QAAQ;GACd,MAAM,MAAM,MAAM;GAClB,MAAM,MAAM,MAAM;EACpB,CACF;;GAIE,OAAAC,UAAA,GAAAC,mBAsDM,OAtDNC,WAsDM;IArDJ,WAAQ;IACR,OAAM;GACEJ,GAAAA,KAAAA,MAAM,GAAA,CAGdK,YAaUC,iBAAA;IAZP,eAAaC,MAAA,SAAA;IACd,SAAQ;IACR,MAAA;IACA,WAAQ;IACP,uBAAkB,OAAA,OAAA,OAAA,MAAA,WAAE,kBAAkB,MAAM;;IAE7C,SAAAC,cAES,CAFTH,YAESI,gBAAA,EAFD,OAAM,MAAK,GAAA;KAAC,SAAAD,cAEpB,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CAFoBE,gBAAA,SAEpB,EAAA,CAAA,EAAA,CAAA;;IACAL,CAAAA,GAAAA,YAESI,gBAAA,EAFD,OAAM,MAAK,GAAA;KAAC,SAAAD,cAEpB,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CAFoBE,gBAAA,SAEpB,EAAA,CAAA,EAAA,CAAA;;;;GAGMH,GAAAA,GAAAA,CAAAA,aAAAA,CAAAA,GAAAA,MAAA,SAAA,MAAS,SADjBL,UAAA,GAAAS,YAeeC,sBAAA;;IAbJ,YAAAL,MAAA,KAAA,CAAK,CAAC;IAAN,uBAAA,CAAA,OAAA,OAAA,OAAA,MAAA,WAAA,MAAA,KAAA,CAAK,CAAC,MAAG,SAOG,OAAA,OAAA,OAAA,MAAA,WAAAA,MAAA,aAAA,CAAa,CAACA,MAAA,SAAA,GAAW,MAAM,EAAA;IANpD,OAAM;IACN,WAAU;IACV,OAAM;IACN,cAAW;IACX,OAAA;IACA,gBAAA;IAEC,QAAI,OAAA,OAAA,OAAA,MAAA,WAAEA,MAAA,YAAA,CAAY,CAACA,MAAA,SAAA,GAAW,MAAM;;IAE1B,SAAOC,cAC8B,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CAA9CK,mBAA8C,QAAA,EAAxC,OAAM,0BAAyB,GAAC,KAAC,EAAA,CAAA,EAAA,CAAA;;GAG3CX,GAAAA,GAAAA,CAAAA,YAAAA,CAAAA,MAAAA,UAAA,GAAAC,mBAiBM,OAjBN,YAiBM,EAbJD,UAAA,IAAA,GAAAC,mBAYEW,UAAA,MAAAC,WAXiBR,MAAA,KAAA,CAAK,CAAC,MAAf,GAAG,MAAC;IADd,OAAAL,UAAA,GAAAS,YAYEC,sBAAA;KAVC,KAAK;KACL,eAAa,EAAE,SAAQ;KACxB,OAAM;KACN,WAAU;KACV,OAAM;KACL,cAAY,aAAa;KAC1B,OAAA;KACA,gBAAA;KACC,wBAAkB,WAAEL,MAAA,aAAA,CAAa,CAACA,MAAA,SAAA,GAAW,QAAQ,CAAC;KACtD,SAAI,WAAEA,MAAA,YAAA,CAAY,CAACA,MAAA,SAAA,GAAW,QAAQ,CAAC"}
1
+ {"version":3,"file":"RuiColorInput.vue_vue_type_script_setup_true_lang.js","names":["$attrs","_useModel","_openBlock","_createElementBlock","_mergeProps","_createVNode","RuiTabs","_unref","_withCtx","RuiTab","_createTextVNode","_createBlock","RuiTextField","_createElementVNode","_Fragment","_renderList"],"sources":["../../../src/components/color-picker/RuiColorInput.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type { Color, ColorFormat } from './utils';\nimport { clamp } from '@vueuse/shared';\nimport tinycolor from 'tinycolor2';\nimport RuiTextField from '@/components/forms/text-field/RuiTextField.vue';\nimport RuiTab from '@/components/tabs/tab/RuiTab.vue';\nimport RuiTabs from '@/components/tabs/tabs/RuiTabs.vue';\n\ndefineOptions({\n name: 'RuiColorInput',\n inheritAttrs: false,\n});\n\nconst modelValue = defineModel<Color>({ required: true });\n\nconst MAX_RGB = 255;\nconst VALID_HEX_LENGTHS = [3, 4, 6];\nconst DEFAULT_HEX = '000000';\nconst RGB_CHANNELS = ['Red', 'Green', 'Blue'];\n\nconst inputType = ref<ColorFormat>('hex');\nconst state = reactive({\n color: get(modelValue),\n hex: get(modelValue).hex,\n rgb: get(modelValue).rgb,\n});\n\nfunction applyRgbValue(value: string, key: number): void {\n if (!state.rgb || !state.color)\n return;\n\n const clamped = clamp(Number(value), 0, MAX_RGB);\n state.rgb[key] = clamped;\n const [r, g, b] = state.rgb;\n state.color.hex = tinycolor({ r, g, b }).toHex();\n}\n\nconst onBlurChange = useDebounceFn((format: ColorFormat, event: Event, key?: number) => {\n if (!state.color)\n return;\n\n const target = event.target;\n if (!(target instanceof HTMLInputElement))\n return;\n\n const value = target.value;\n if (format === 'hex') {\n const hex = value.replace('#', '');\n if (tinycolor(hex).isValid() && VALID_HEX_LENGTHS.includes(hex.length))\n state.color.hex = hex;\n else state.color.hex = DEFAULT_HEX;\n }\n else if (key !== undefined) {\n applyRgbValue(value, key);\n }\n\n set(modelValue, state.color);\n}, 100);\n\nconst onInputChange = useDebounceFn((format: ColorFormat, value: string, key?: number) => {\n if (!value)\n return;\n\n if (format === 'hex') {\n const hex = value.replace('#', '');\n if (tinycolor(hex).isValid() && state.color && hex.length === 6)\n state.color.hex = hex;\n }\n else if (key !== undefined) {\n applyRgbValue(value, key);\n }\n\n set(modelValue, state.color);\n}, 300);\n\nfunction onInputTypeChange(value: string | number): void {\n if (value === 'hex' || value === 'rgb')\n set(inputType, value);\n}\n\nwatch(\n () => {\n const color = get(modelValue);\n return [color.hex, ...color.rgb] as const;\n },\n () => {\n const color = get(modelValue);\n state.color = color;\n state.hex = color.hex;\n state.rgb = color.rgb;\n },\n);\n</script>\n\n<template>\n <div\n data-id=\"color-input\"\n class=\"flex flex-col gap-2 w-full\"\n v-bind=\"$attrs\"\n >\n <!-- the format is a choice between two views of one value, which is what a segmented control is for -->\n <RuiTabs\n :model-value=\"inputType\"\n variant=\"segmented\"\n grow\n data-id=\"color-format\"\n @update:model-value=\"onInputTypeChange($event)\"\n >\n <RuiTab value=\"hex\">\n Hex\n </RuiTab>\n <RuiTab value=\"rgb\">\n RGB\n </RuiTab>\n </RuiTabs>\n <RuiTextField\n v-if=\"inputType === 'hex'\"\n v-model=\"state.hex\"\n class=\"w-full [&_input]:uppercase\"\n maxlength=\"6\"\n color=\"primary\"\n aria-label=\"Hex color\"\n dense\n details=\"hidden\"\n @update:model-value=\"onInputChange(inputType, $event)\"\n @blur=\"onBlurChange(inputType, $event)\"\n >\n <template #prepend>\n <span class=\"text-rui-text-secondary\">#</span>\n </template>\n </RuiTextField>\n <div\n v-else\n class=\"flex gap-1\"\n >\n <RuiTextField\n v-for=\"(v, i) in state.rgb\"\n :key=\"i\"\n :model-value=\"v.toString()\"\n class=\"[&_input]:text-center w-full\"\n maxlength=\"3\"\n color=\"primary\"\n :aria-label=\"RGB_CHANNELS[i]\"\n dense\n details=\"hidden\"\n @update:model-value=\"onInputChange(inputType, $event, i)\"\n @blur=\"onBlurChange(inputType, $event, i)\"\n />\n </div>\n </div>\n</template>\n"],"mappings":"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"}