ropav 0.0.2 → 0.0.3

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 (74) hide show
  1. package/README.md +32 -3
  2. package/dist/base.css +125 -88
  3. package/dist/button.css +259 -32
  4. package/dist/button.js +51 -19
  5. package/dist/button.js.map +1 -1
  6. package/dist/checkbox.css +125 -21
  7. package/dist/checkbox.js +77 -42
  8. package/dist/checkbox.js.map +1 -1
  9. package/dist/components/button/button.d.ts +2 -2
  10. package/dist/components/button/index.d.ts +1 -1
  11. package/dist/components/button/types.d.ts +8 -1
  12. package/dist/components/checkbox/index.d.ts +1 -1
  13. package/dist/components/checkbox/types.d.ts +8 -0
  14. package/dist/components/input/index.d.ts +1 -1
  15. package/dist/components/input/input.d.ts +5 -1
  16. package/dist/components/input/types.d.ts +5 -0
  17. package/dist/components/radio/index.d.ts +1 -1
  18. package/dist/components/radio/types.d.ts +12 -0
  19. package/dist/components/select/types.d.ts +3 -0
  20. package/dist/components/select/useSelect.d.ts +2 -0
  21. package/dist/components/switch/index.d.ts +1 -1
  22. package/dist/components/switch/types.d.ts +4 -0
  23. package/dist/components/textarea/index.d.ts +1 -1
  24. package/dist/components/textarea/types.d.ts +5 -0
  25. package/dist/components/textarea/useTextarea.d.ts +1 -0
  26. package/dist/index.d.ts +0 -2
  27. package/dist/index.js +2 -4
  28. package/dist/input.css +87 -21
  29. package/dist/input.js +66 -23
  30. package/dist/input.js.map +1 -1
  31. package/dist/radio.css +82 -18
  32. package/dist/radio.js +35 -8
  33. package/dist/radio.js.map +1 -1
  34. package/dist/select.css +104 -39
  35. package/dist/select.js +149 -87
  36. package/dist/select.js.map +1 -1
  37. package/dist/switch.css +75 -20
  38. package/dist/switch.js +8 -4
  39. package/dist/switch.js.map +1 -1
  40. package/dist/textarea.css +80 -20
  41. package/dist/textarea.js +33 -5
  42. package/dist/textarea.js.map +1 -1
  43. package/dist/useControlState.js +4 -0
  44. package/dist/useControlState.js.map +1 -1
  45. package/package.json +9 -9
  46. package/src/styles/_mixins.scss +18 -8
  47. package/src/styles/_tokens.scss +130 -99
  48. package/src/styles/_variables.scss +28 -28
  49. package/dist/components/_internal/icons/CheckIcon.d.ts +0 -18
  50. package/dist/components/_internal/icons/ChevronDownIcon.d.ts +0 -18
  51. package/dist/components/_internal/icons/MinusIcon.d.ts +0 -18
  52. package/dist/components/_internal/icons/index.d.ts +0 -3
  53. package/dist/components/_internal/optionList.d.ts +0 -9
  54. package/dist/components/tabs/index.d.ts +0 -5
  55. package/dist/components/tabs/index.js +0 -2
  56. package/dist/components/tabs/tab-panel.d.ts +0 -21
  57. package/dist/components/tabs/tabs-list.d.ts +0 -20
  58. package/dist/components/tabs/tabs-trigger.d.ts +0 -21
  59. package/dist/components/tabs/tabs.d.ts +0 -23
  60. package/dist/components/tabs/types.d.ts +0 -18
  61. package/dist/components/tabs/useTabs.d.ts +0 -19
  62. package/dist/components/tooltip/index.d.ts +0 -2
  63. package/dist/components/tooltip/index.js +0 -2
  64. package/dist/components/tooltip/tooltip.d.ts +0 -23
  65. package/dist/components/tooltip/types.d.ts +0 -5
  66. package/dist/components/tooltip/useTooltip.d.ts +0 -8
  67. package/dist/tabs.css +0 -45
  68. package/dist/tabs.js +0 -205
  69. package/dist/tabs.js.map +0 -1
  70. package/dist/tooltip.css +0 -78
  71. package/dist/tooltip.js +0 -112
  72. package/dist/tooltip.js.map +0 -1
  73. package/dist/useRequiredInject.js +0 -11
  74. package/dist/useRequiredInject.js.map +0 -1
package/dist/switch.js CHANGED
@@ -8,7 +8,9 @@ function useSwitch(props, emitUpdate) {
8
8
  const rootClass = computed(() => bem("rp-switch", {
9
9
  checked: props.modelValue,
10
10
  disabled: control.disabled,
11
- invalid: control.invalid
11
+ invalid: control.invalid,
12
+ [`color-${props.color}`]: Boolean(props.color),
13
+ [`size-${props.size}`]: Boolean(props.size)
12
14
  }));
13
15
  function onChange(e) {
14
16
  emitUpdate(e.target.checked);
@@ -21,8 +23,8 @@ function useSwitch(props, emitUpdate) {
21
23
  }
22
24
  //#endregion
23
25
  //#region src/components/switch/switch.vue?vue&type=script&setup=true&vapor=true&lang.ts
24
- var t0 = template("<span data-v-8d0cc56f class=rp-switch__label>");
25
- var t1 = template("<label data-v-8d0cc56f><input data-v-8d0cc56f type=checkbox class=rp-switch__native role=switch><span data-v-8d0cc56f class=rp-switch__track><span data-v-8d0cc56f class=rp-switch__thumb></span></span>", 1);
26
+ var t0 = template("<span data-v-aeef0d94 class=rp-switch__label>");
27
+ var t1 = template("<label data-v-aeef0d94><input data-v-aeef0d94 type=checkbox class=rp-switch__native role=switch><span data-v-aeef0d94 class=rp-switch__track><span data-v-aeef0d94 class=rp-switch__thumb></span></span>", 1);
26
28
  //#endregion
27
29
  //#region src/components/switch/switch.vue
28
30
  var switch_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineVaporComponent({
@@ -32,6 +34,8 @@ var switch_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE_
32
34
  id: {},
33
35
  name: {},
34
36
  modelValue: { type: Boolean },
37
+ color: {},
38
+ size: {},
35
39
  disabled: {
36
40
  type: Boolean,
37
41
  default: void 0
@@ -87,7 +91,7 @@ var switch_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE_
87
91
  });
88
92
  return n5;
89
93
  }
90
- }), [["__scopeId", "data-v-8d0cc56f"]]);
94
+ }), [["__scopeId", "data-v-aeef0d94"]]);
91
95
  //#endregion
92
96
  export { switch_default as t };
93
97
 
@@ -1 +1 @@
1
- {"version":3,"file":"switch.js","names":[],"sources":["../src/components/switch/useSwitch.ts","../src/components/switch/switch.vue","../src/components/switch/switch.vue"],"sourcesContent":["import { computed } from 'vue';\nimport { useControlState } from '@/composables/useControlState';\nimport { bem } from '@/utils/bem';\nimport type { SwitchProps } from './types';\n\nexport function useSwitch(\n props: Readonly<SwitchProps>,\n emitUpdate: (value: boolean) => void,\n) {\n const control = useControlState(props);\n\n const rootClass = computed(() =>\n bem('rp-switch', {\n checked: props.modelValue,\n disabled: control.disabled,\n invalid: control.invalid,\n }),\n );\n\n function onChange(e: Event) {\n emitUpdate((e.target as HTMLInputElement).checked);\n }\n\n return {\n control,\n rootClass,\n onChange,\n };\n}\n","<template>\n <label :class=\"rootClass\" :data-disabled=\"control.disabled || undefined\" :data-state=\"modelValue ? 'checked' : 'unchecked'\">\n <input\n :id=\"control.id\"\n :name=\"name\"\n type=\"checkbox\"\n class=\"rp-switch__native\"\n role=\"switch\"\n :checked=\"modelValue\"\n :disabled=\"control.disabled || undefined\"\n :required=\"control.required || undefined\"\n :aria-checked=\"modelValue\"\n :aria-label=\"ariaLabel || undefined\"\n :aria-labelledby=\"control.ariaLabelledby\"\n :aria-describedby=\"control.ariaDescribedby\"\n :aria-invalid=\"control.invalid || undefined\"\n :aria-required=\"control.required || undefined\"\n @change=\"onChange\"\n />\n <span class=\"rp-switch__track\">\n <span class=\"rp-switch__thumb\" />\n </span>\n <span v-if=\"$slots.default\" class=\"rp-switch__label\">\n <slot />\n </span>\n </label>\n</template>\n\n<script lang=\"ts\" setup vapor>\nimport { useSwitch } from './useSwitch';\nimport type { SwitchProps } from './types';\n\ndefineOptions({ name: 'RpSwitch' });\n\nconst props = withDefaults(defineProps<SwitchProps>(), {\n disabled: undefined,\n required: undefined,\n invalid: undefined,\n});\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: boolean];\n}>();\n\nconst { control, rootClass, onChange } = useSwitch(props, (value) => {\n emit('update:modelValue', value);\n});\n</script>\n\n<style src=\"./switch.scss\" lang=\"scss\" scoped></style>\n","<template>\n <label :class=\"rootClass\" :data-disabled=\"control.disabled || undefined\" :data-state=\"modelValue ? 'checked' : 'unchecked'\">\n <input\n :id=\"control.id\"\n :name=\"name\"\n type=\"checkbox\"\n class=\"rp-switch__native\"\n role=\"switch\"\n :checked=\"modelValue\"\n :disabled=\"control.disabled || undefined\"\n :required=\"control.required || undefined\"\n :aria-checked=\"modelValue\"\n :aria-label=\"ariaLabel || undefined\"\n :aria-labelledby=\"control.ariaLabelledby\"\n :aria-describedby=\"control.ariaDescribedby\"\n :aria-invalid=\"control.invalid || undefined\"\n :aria-required=\"control.required || undefined\"\n @change=\"onChange\"\n />\n <span class=\"rp-switch__track\">\n <span class=\"rp-switch__thumb\" />\n </span>\n <span v-if=\"$slots.default\" class=\"rp-switch__label\">\n <slot />\n </span>\n </label>\n</template>\n\n<script lang=\"ts\" setup vapor>\nimport { useSwitch } from './useSwitch';\nimport type { SwitchProps } from './types';\n\ndefineOptions({ name: 'RpSwitch' });\n\nconst props = withDefaults(defineProps<SwitchProps>(), {\n disabled: undefined,\n required: undefined,\n invalid: undefined,\n});\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: boolean];\n}>();\n\nconst { control, rootClass, onChange } = useSwitch(props, (value) => {\n emit('update:modelValue', value);\n});\n</script>\n\n<style src=\"./switch.scss\" lang=\"scss\" scoped></style>\n"],"mappings":";;;;AAKA,SAAgB,UACZ,OACA,YACF;CACE,MAAM,UAAU,gBAAgB,KAAK;CAErC,MAAM,YAAY,eACd,IAAI,aAAa;EACb,SAAS,MAAM;EACf,UAAU,QAAQ;EAClB,SAAS,QAAQ;CACrB,CAAC,CACL;CAEA,SAAS,SAAS,GAAU;EACxB,WAAY,EAAE,OAA4B,OAAO;CACrD;CAEA,OAAO;EACH;EACA;EACA;CACJ;AACJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ECMA,MAAM,QAAQ;EAMd,MAAM,OAAO;EAIb,MAAM,EAAE,SAAS,WAAW,aAAa,UAAU,QAAQ,UAAU;GACjE,KAAK,qBAAqB,KAAK;EACnC,CAAC;;;SA7BY,WAAM,MAAE,MAAA,QAAA,CAAQ,CAAA,CAAA,CAAA;;;;;;gBAhBV,MAAA,SAAA,CAAS;eAAG,iBAAe,qBAAoB,KAAA,CAAS;eAAG,cAAY,cAAU,YAAA,WAAA;eAEvF,MAAI,SAAO,EAAA;eACX,QAAM,QAAA,IAAI;eAIV,WAAS,WAAU;eACnB,YAAU,qBAAoB,KAAA,CAAS;eACvC,YAAU,qBAAoB,KAAA,CAAS;eACvC,gBAAc,WAAU;eACxB,cAAY,QAAA,aAAa,KAAA,CAAS;eAClC,mBAAiB,SAAO,cAAA;eACxB,oBAAkB,SAAO,eAAA;eACzB,gBAAc,SAAO,WAAY,KAAA,CAAS;eAC1C,iBAAe,qBAAoB,KAAA,CAAS;;;iBAMrC,OAAM,eAAA"}
1
+ {"version":3,"file":"switch.js","names":[],"sources":["../src/components/switch/useSwitch.ts","../src/components/switch/switch.vue","../src/components/switch/switch.vue"],"sourcesContent":["import { computed } from 'vue';\nimport { useControlState } from '@/composables/useControlState';\nimport { bem } from '@/utils/bem';\nimport type { SwitchProps } from './types';\n\nexport function useSwitch(props: Readonly<SwitchProps>, emitUpdate: (value: boolean) => void) {\n const control = useControlState(props);\n\n const rootClass = computed(() =>\n bem('rp-switch', {\n checked: props.modelValue,\n disabled: control.disabled,\n invalid: control.invalid,\n [`color-${props.color}`]: Boolean(props.color),\n [`size-${props.size}`]: Boolean(props.size),\n }),\n );\n\n function onChange(e: Event) {\n emitUpdate((e.target as HTMLInputElement).checked);\n }\n\n return {\n control,\n rootClass,\n onChange,\n };\n}\n","<template>\n <label\n :class=\"rootClass\"\n :data-disabled=\"control.disabled || undefined\"\n :data-state=\"modelValue ? 'checked' : 'unchecked'\"\n >\n <input\n :id=\"control.id\"\n :name=\"name\"\n type=\"checkbox\"\n class=\"rp-switch__native\"\n role=\"switch\"\n :checked=\"modelValue\"\n :disabled=\"control.disabled || undefined\"\n :required=\"control.required || undefined\"\n :aria-checked=\"modelValue\"\n :aria-label=\"ariaLabel || undefined\"\n :aria-labelledby=\"control.ariaLabelledby\"\n :aria-describedby=\"control.ariaDescribedby\"\n :aria-invalid=\"control.invalid || undefined\"\n :aria-required=\"control.required || undefined\"\n @change=\"onChange\"\n />\n <span class=\"rp-switch__track\">\n <span class=\"rp-switch__thumb\" />\n </span>\n <span v-if=\"$slots.default\" class=\"rp-switch__label\">\n <slot />\n </span>\n </label>\n</template>\n\n<script lang=\"ts\" setup vapor>\nimport { useSwitch } from './useSwitch';\nimport type { SwitchProps } from './types';\n\ndefineOptions({ name: 'RpSwitch' });\n\nconst props = withDefaults(defineProps<SwitchProps>(), {\n disabled: undefined,\n required: undefined,\n invalid: undefined,\n});\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: boolean];\n}>();\n\nconst { control, rootClass, onChange } = useSwitch(props, (value) => {\n emit('update:modelValue', value);\n});\n</script>\n\n<style src=\"./switch.scss\" lang=\"scss\" scoped></style>\n","<template>\n <label\n :class=\"rootClass\"\n :data-disabled=\"control.disabled || undefined\"\n :data-state=\"modelValue ? 'checked' : 'unchecked'\"\n >\n <input\n :id=\"control.id\"\n :name=\"name\"\n type=\"checkbox\"\n class=\"rp-switch__native\"\n role=\"switch\"\n :checked=\"modelValue\"\n :disabled=\"control.disabled || undefined\"\n :required=\"control.required || undefined\"\n :aria-checked=\"modelValue\"\n :aria-label=\"ariaLabel || undefined\"\n :aria-labelledby=\"control.ariaLabelledby\"\n :aria-describedby=\"control.ariaDescribedby\"\n :aria-invalid=\"control.invalid || undefined\"\n :aria-required=\"control.required || undefined\"\n @change=\"onChange\"\n />\n <span class=\"rp-switch__track\">\n <span class=\"rp-switch__thumb\" />\n </span>\n <span v-if=\"$slots.default\" class=\"rp-switch__label\">\n <slot />\n </span>\n </label>\n</template>\n\n<script lang=\"ts\" setup vapor>\nimport { useSwitch } from './useSwitch';\nimport type { SwitchProps } from './types';\n\ndefineOptions({ name: 'RpSwitch' });\n\nconst props = withDefaults(defineProps<SwitchProps>(), {\n disabled: undefined,\n required: undefined,\n invalid: undefined,\n});\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: boolean];\n}>();\n\nconst { control, rootClass, onChange } = useSwitch(props, (value) => {\n emit('update:modelValue', value);\n});\n</script>\n\n<style src=\"./switch.scss\" lang=\"scss\" scoped></style>\n"],"mappings":";;;;AAKA,SAAgB,UAAU,OAA8B,YAAsC;CAC1F,MAAM,UAAU,gBAAgB,KAAK;CAErC,MAAM,YAAY,eACd,IAAI,aAAa;EACb,SAAS,MAAM;EACf,UAAU,QAAQ;EAClB,SAAS,QAAQ;GAChB,SAAS,MAAM,UAAU,QAAQ,MAAM,KAAK;GAC5C,QAAQ,MAAM,SAAS,QAAQ,MAAM,IAAI;CAC9C,CAAC,CACL;CAEA,SAAS,SAAS,GAAU;EACxB,WAAY,EAAE,OAA4B,OAAO;CACrD;CAEA,OAAO;EACH;EACA;EACA;CACJ;AACJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ECWA,MAAM,QAAQ;EAMd,MAAM,OAAO;EAIb,MAAM,EAAE,SAAS,WAAW,aAAa,UAAU,QAAQ,UAAU;GACjE,KAAK,qBAAqB,KAAK;EACnC,CAAC;;;SA7BY,WAAM,MAAE,MAAA,QAAA,CAAQ,CAAA,CAAA,CAAA;;;;;;gBAnBb,MAAA,SAAA,CAAS;eAChB,iBAAe,qBAAoB,KAAA,CAAS;eAC5C,cAAY,cAAU,YAAA,WAAA;eAGlB,MAAI,SAAO,EAAA;eACX,QAAM,QAAA,IAAI;eAIV,WAAS,WAAU;eACnB,YAAU,qBAAoB,KAAA,CAAS;eACvC,YAAU,qBAAoB,KAAA,CAAS;eACvC,gBAAc,WAAU;eACxB,cAAY,QAAA,aAAa,KAAA,CAAS;eAClC,mBAAiB,SAAO,cAAA;eACxB,oBAAkB,SAAO,eAAA;eACzB,gBAAc,SAAO,WAAY,KAAA,CAAS;eAC1C,iBAAe,qBAAoB,KAAA,CAAS;;;iBAMrC,OAAM,eAAA"}
package/dist/textarea.css CHANGED
@@ -1,46 +1,106 @@
1
- .rp-textarea[data-v-84020885] {
1
+ .rp-textarea[data-v-2c68871d] {
2
+ --_rp-textarea-padding-y: var(--rp-spacing-3);
3
+ --_rp-textarea-padding-x: var(--rp-spacing-3);
4
+ --_rp-textarea-font-size: var(--rp-font-size-base);
5
+ --_rp-textarea-radius: var(--rp-radius-sm);
2
6
  display: inline-flex;
7
+ box-sizing: border-box;
3
8
  font-family: var(--rp-font-family);
4
9
  font-weight: var(--rp-font-weight-normal);
5
- background-color: var(--rp-color-control-bg);
6
- border: var(--rp-border-width-thin) solid var(--rp-color-control-border);
10
+ background-color: var(--rp-color-button-default-bg);
11
+ border: var(--rp-border-width-thin) solid var(--rp-color-border);
12
+ cursor: text;
7
13
  transition: border-color var(--rp-transition-fast), box-shadow var(--rp-transition-fast);
8
14
  }
9
- .rp-textarea[data-v-84020885]:hover:not(.rp-textarea--disabled) {
10
- border-color: var(--rp-color-control-border-hover);
15
+ .rp-textarea[data-v-2c68871d]:hover:not(.rp-textarea--disabled):not(.rp-textarea--invalid):not(.rp-textarea--valid) {
16
+ border-color: var(--rp-color-border-hover);
11
17
  }
12
- .rp-textarea[data-v-84020885]:focus-within:not(.rp-textarea--disabled) {
13
- border-color: var(--rp-color-control-border-focus);
18
+ .rp-textarea[data-v-2c68871d]:focus-within:not(.rp-textarea--disabled):not(.rp-textarea--invalid):not(.rp-textarea--valid) {
19
+ border-color: var(--rp-color-primary);
14
20
  box-shadow: 0 0 0 var(--rp-border-width-medium) var(--rp-color-focus-ring);
15
21
  }
16
- .rp-textarea[data-v-84020885] {
17
- padding: var(--rp-spacing-3) var(--rp-spacing-4);
18
- font-size: var(--rp-font-size-base);
19
- border-radius: var(--rp-radius-lg);
22
+ .rp-textarea[data-v-2c68871d] {
23
+ padding: var(--_rp-textarea-padding-y) var(--_rp-textarea-padding-x);
24
+ font-size: var(--_rp-textarea-font-size);
25
+ border-radius: var(--_rp-textarea-radius);
20
26
  }
21
- .rp-textarea--disabled[data-v-84020885] {
27
+ .rp-textarea--size-xs[data-v-2c68871d] {
28
+ --_rp-textarea-padding-y: var(--rp-spacing-1);
29
+ --_rp-textarea-padding-x: var(--rp-spacing-1);
30
+ --_rp-textarea-font-size: var(--rp-font-size-xs);
31
+ }
32
+ .rp-textarea--size-sm[data-v-2c68871d] {
33
+ --_rp-textarea-padding-y: var(--rp-spacing-2);
34
+ --_rp-textarea-padding-x: var(--rp-spacing-2);
35
+ --_rp-textarea-font-size: var(--rp-font-size-sm);
36
+ }
37
+ .rp-textarea--size-md[data-v-2c68871d] {
38
+ --_rp-textarea-padding-y: var(--rp-spacing-3);
39
+ --_rp-textarea-padding-x: var(--rp-spacing-3);
40
+ --_rp-textarea-font-size: var(--rp-font-size-base);
41
+ }
42
+ .rp-textarea--size-lg[data-v-2c68871d] {
43
+ --_rp-textarea-padding-y: var(--rp-spacing-4);
44
+ --_rp-textarea-padding-x: var(--rp-spacing-4);
45
+ --_rp-textarea-font-size: var(--rp-font-size-lg);
46
+ }
47
+ .rp-textarea--size-xl[data-v-2c68871d] {
48
+ --_rp-textarea-padding-y: var(--rp-spacing-5);
49
+ --_rp-textarea-padding-x: var(--rp-spacing-5);
50
+ --_rp-textarea-font-size: var(--rp-font-size-lg);
51
+ }
52
+ .rp-textarea--radius-xs[data-v-2c68871d] {
53
+ --_rp-textarea-radius: var(--rp-radius-sm);
54
+ }
55
+ .rp-textarea--radius-sm[data-v-2c68871d] {
56
+ --_rp-textarea-radius: var(--rp-radius-sm);
57
+ }
58
+ .rp-textarea--radius-md[data-v-2c68871d] {
59
+ --_rp-textarea-radius: var(--rp-radius-md);
60
+ }
61
+ .rp-textarea--radius-lg[data-v-2c68871d] {
62
+ --_rp-textarea-radius: var(--rp-radius-lg);
63
+ }
64
+ .rp-textarea--radius-xl[data-v-2c68871d] {
65
+ --_rp-textarea-radius: var(--rp-radius-xl);
66
+ }
67
+ .rp-textarea--disabled[data-v-2c68871d] {
22
68
  opacity: var(--rp-opacity-disabled);
23
69
  cursor: not-allowed;
24
70
  }
25
- .rp-textarea--invalid[data-v-84020885] {
71
+ .rp-textarea--valid[data-v-2c68871d] {
72
+ border-color: var(--rp-color-success-fg);
73
+ }
74
+ .rp-textarea--valid[data-v-2c68871d]:focus-within:not(.rp-textarea--disabled) {
75
+ border-color: var(--rp-color-success-fg);
76
+ box-shadow: 0 0 0 var(--rp-border-width-medium) color-mix(in srgb, var(--rp-color-success-fg) 32%, transparent);
77
+ }
78
+ .rp-textarea--invalid[data-v-2c68871d] {
79
+ border-color: var(--rp-color-danger-fg);
80
+ }
81
+ .rp-textarea--invalid[data-v-2c68871d]:focus-within:not(.rp-textarea--disabled) {
26
82
  border-color: var(--rp-color-danger-fg);
83
+ box-shadow: 0 0 0 var(--rp-border-width-medium) color-mix(in srgb, var(--rp-color-danger-fg) 32%, transparent);
27
84
  }
28
- .rp-textarea--readonly[data-v-84020885] {
29
- background-color: var(--rp-color-control-readonly-bg);
85
+ .rp-textarea--readonly[data-v-2c68871d] {
86
+ background-color: var(--rp-color-surface-muted);
30
87
  }
31
- .rp-textarea__native[data-v-84020885] {
88
+ .rp-textarea__native[data-v-2c68871d] {
89
+ box-sizing: border-box;
32
90
  flex: 1;
91
+ width: 100%;
33
92
  min-width: 0;
93
+ padding: 0;
34
94
  border: none;
35
95
  outline: none;
36
96
  background: transparent;
37
97
  font: inherit;
38
- color: var(--rp-color-control-fg);
98
+ color: var(--rp-color-text);
39
99
  line-height: var(--rp-line-height-relaxed);
40
100
  }
41
- .rp-textarea__native[data-v-84020885]::placeholder {
42
- color: var(--rp-color-control-placeholder);
101
+ .rp-textarea__native[data-v-2c68871d]::placeholder {
102
+ color: var(--rp-color-text-secondary);
43
103
  }
44
- .rp-textarea__native[data-v-84020885]:disabled {
104
+ .rp-textarea__native[data-v-2c68871d]:disabled {
45
105
  cursor: not-allowed;
46
106
  }
package/dist/textarea.js CHANGED
@@ -3,26 +3,47 @@ import { n as bem, t as _plugin_vue_export_helper_default } from "./_plugin-vue_
3
3
  import { t as useControlState } from "./useControlState.js";
4
4
  import { child, computed, createInvoker, defineVaporComponent, delegateEvents, renderEffect, setAttr, setClass, setProp, setValue, template, unref } from "vue";
5
5
  //#region src/components/textarea/useTextarea.ts
6
+ function isInteractiveElement(target) {
7
+ return Boolean(target.closest([
8
+ "button",
9
+ "a[href]",
10
+ "input",
11
+ "select",
12
+ "textarea:not(.rp-textarea__native)",
13
+ "[contenteditable=\"true\"]",
14
+ "[tabindex]:not([tabindex=\"-1\"])"
15
+ ].join(",")));
16
+ }
6
17
  function useTextarea(props, emitUpdate) {
7
18
  const control = useControlState(props);
8
19
  const rootClass = computed(() => bem("rp-textarea", {
20
+ [`size-${props.size}`]: Boolean(props.size),
21
+ [`radius-${props.radius}`]: Boolean(props.radius),
9
22
  disabled: control.disabled,
10
23
  invalid: control.invalid,
24
+ valid: control.valid && !control.invalid,
11
25
  readonly: props.readonly
12
26
  }));
13
27
  function onInput(e) {
14
28
  emitUpdate(e.target.value);
15
29
  }
30
+ function focusTextarea(e) {
31
+ if (control.disabled) return;
32
+ const target = e.target;
33
+ if (target instanceof Element && isInteractiveElement(target)) return;
34
+ e.currentTarget.querySelector(".rp-textarea__native")?.focus();
35
+ }
16
36
  return {
17
37
  control,
18
38
  rootClass,
19
- onInput
39
+ onInput,
40
+ focusTextarea
20
41
  };
21
42
  }
22
43
  //#endregion
23
44
  //#region src/components/textarea/textarea.vue?vue&type=script&setup=true&vapor=true&lang.ts
24
- var t0 = template("<div data-v-84020885><textarea data-v-84020885 class=rp-textarea__native>", 1);
25
- delegateEvents("input");
45
+ var t0 = template("<div data-v-2c68871d><textarea data-v-2c68871d class=rp-textarea__native>", 1);
46
+ delegateEvents("input", "mousedown");
26
47
  //#endregion
27
48
  //#region src/components/textarea/textarea.vue
28
49
  var textarea_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineVaporComponent({
@@ -32,6 +53,8 @@ var textarea_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PUR
32
53
  id: {},
33
54
  name: {},
34
55
  modelValue: {},
56
+ size: {},
57
+ radius: {},
35
58
  placeholder: { default: "" },
36
59
  rows: { default: 3 },
37
60
  disabled: {
@@ -50,6 +73,10 @@ var textarea_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PUR
50
73
  type: Boolean,
51
74
  default: void 0
52
75
  },
76
+ valid: {
77
+ type: Boolean,
78
+ default: void 0
79
+ },
53
80
  ariaLabel: {},
54
81
  describedby: {},
55
82
  labelledby: {}
@@ -58,12 +85,13 @@ var textarea_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PUR
58
85
  setup(__props, { emit: __emit }) {
59
86
  const props = __props;
60
87
  const emit = __emit;
61
- const { control, rootClass, onInput } = useTextarea(props, (value) => {
88
+ const { control, rootClass, onInput, focusTextarea } = useTextarea(props, (value) => {
62
89
  emit("update:modelValue", value);
63
90
  });
64
91
  const n1 = t0();
65
92
  const n0 = child(n1);
66
93
  n0.$evtinput = createInvoker((e) => unref(onInput)(e));
94
+ n1.$evtmousedown = createInvoker((e) => unref(focusTextarea)(e));
67
95
  renderEffect(() => {
68
96
  const _control = unref(control);
69
97
  const _control_required = _control.required;
@@ -84,7 +112,7 @@ var textarea_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PUR
84
112
  });
85
113
  return n1;
86
114
  }
87
- }), [["__scopeId", "data-v-84020885"]]);
115
+ }), [["__scopeId", "data-v-2c68871d"]]);
88
116
  //#endregion
89
117
  export { textarea_default as t };
90
118
 
@@ -1 +1 @@
1
- {"version":3,"file":"textarea.js","names":[],"sources":["../src/components/textarea/useTextarea.ts","../src/components/textarea/textarea.vue","../src/components/textarea/textarea.vue"],"sourcesContent":["import { computed } from 'vue';\nimport { useControlState } from '@/composables/useControlState';\nimport { bem } from '@/utils/bem';\nimport type { TextareaProps } from './types';\n\nexport function useTextarea(\n props: Readonly<TextareaProps>,\n emitUpdate: (value: string) => void,\n) {\n const control = useControlState(props);\n\n const rootClass = computed(() =>\n bem('rp-textarea', {\n disabled: control.disabled,\n invalid: control.invalid,\n readonly: props.readonly,\n }),\n );\n\n function onInput(e: Event) {\n emitUpdate((e.target as HTMLTextAreaElement).value);\n }\n\n return {\n control,\n rootClass,\n onInput,\n };\n}\n","<template>\n <div :class=\"rootClass\">\n <textarea\n :id=\"control.id\"\n :name=\"name\"\n class=\"rp-textarea__native\"\n :value=\"modelValue\"\n :placeholder=\"placeholder\"\n :rows=\"rows\"\n :disabled=\"control.disabled || undefined\"\n :readonly=\"readonly || undefined\"\n :required=\"control.required || undefined\"\n :aria-label=\"ariaLabel || undefined\"\n :aria-labelledby=\"control.ariaLabelledby\"\n :aria-describedby=\"control.ariaDescribedby\"\n :aria-invalid=\"control.invalid || undefined\"\n :aria-required=\"control.required || undefined\"\n @input=\"onInput\"\n />\n </div>\n</template>\n\n<script lang=\"ts\" setup vapor>\nimport { useTextarea } from './useTextarea';\nimport type { TextareaProps } from './types';\n\ndefineOptions({ name: 'RpTextarea' });\n\nconst props = withDefaults(defineProps<TextareaProps>(), {\n placeholder: '',\n rows: 3,\n disabled: undefined,\n required: undefined,\n invalid: undefined,\n readonly: false,\n});\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string];\n}>();\n\nconst { control, rootClass, onInput } = useTextarea(props, (value) => {\n emit('update:modelValue', value);\n});\n</script>\n\n<style src=\"./textarea.scss\" lang=\"scss\" scoped></style>\n","<template>\n <div :class=\"rootClass\">\n <textarea\n :id=\"control.id\"\n :name=\"name\"\n class=\"rp-textarea__native\"\n :value=\"modelValue\"\n :placeholder=\"placeholder\"\n :rows=\"rows\"\n :disabled=\"control.disabled || undefined\"\n :readonly=\"readonly || undefined\"\n :required=\"control.required || undefined\"\n :aria-label=\"ariaLabel || undefined\"\n :aria-labelledby=\"control.ariaLabelledby\"\n :aria-describedby=\"control.ariaDescribedby\"\n :aria-invalid=\"control.invalid || undefined\"\n :aria-required=\"control.required || undefined\"\n @input=\"onInput\"\n />\n </div>\n</template>\n\n<script lang=\"ts\" setup vapor>\nimport { useTextarea } from './useTextarea';\nimport type { TextareaProps } from './types';\n\ndefineOptions({ name: 'RpTextarea' });\n\nconst props = withDefaults(defineProps<TextareaProps>(), {\n placeholder: '',\n rows: 3,\n disabled: undefined,\n required: undefined,\n invalid: undefined,\n readonly: false,\n});\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string];\n}>();\n\nconst { control, rootClass, onInput } = useTextarea(props, (value) => {\n emit('update:modelValue', value);\n});\n</script>\n\n<style src=\"./textarea.scss\" lang=\"scss\" scoped></style>\n"],"mappings":";;;;AAKA,SAAgB,YACZ,OACA,YACF;CACE,MAAM,UAAU,gBAAgB,KAAK;CAErC,MAAM,YAAY,eACd,IAAI,eAAe;EACf,UAAU,QAAQ;EAClB,SAAS,QAAQ;EACjB,UAAU,MAAM;CACpB,CAAC,CACL;CAEA,SAAS,QAAQ,GAAU;EACvB,WAAY,EAAE,OAA+B,KAAK;CACtD;CAEA,OAAO;EACH;EACA;EACA;CACJ;AACJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ECAA,MAAM,QAAQ;EASd,MAAM,OAAO;EAIb,MAAM,EAAE,SAAS,WAAW,YAAY,YAAY,QAAQ,UAAU;GAClE,KAAK,qBAAqB,KAAK;EACnC,CAAC;;;sCA1BmB,MAAA,OAAA,CAAO,CAAA,CAAA,CAAA;;;;gBAhBV,MAAA,SAAA,CAAS;eAEb,MAAI,SAAO,EAAA;eACX,QAAM,QAAA,IAAI;gBAEH,QAAA,UAAU;eACjB,eAAa,QAAA,WAAW;eACxB,QAAM,QAAA,IAAI;eACV,YAAU,SAAO,YAAa,KAAA,CAAS;eACvC,YAAU,QAAA,YAAY,KAAA,CAAS;eAC/B,YAAU,qBAAoB,KAAA,CAAS;eACvC,cAAY,QAAA,aAAa,KAAA,CAAS;eAClC,mBAAiB,SAAO,cAAA;eACxB,oBAAkB,SAAO,eAAA;eACzB,gBAAc,SAAO,WAAY,KAAA,CAAS;eAC1C,iBAAe,qBAAoB,KAAA,CAAS"}
1
+ {"version":3,"file":"textarea.js","names":[],"sources":["../src/components/textarea/useTextarea.ts","../src/components/textarea/textarea.vue","../src/components/textarea/textarea.vue"],"sourcesContent":["import { computed } from 'vue';\nimport { useControlState } from '@/composables/useControlState';\nimport { bem } from '@/utils/bem';\nimport type { TextareaProps } from './types';\n\nfunction isInteractiveElement(target: Element) {\n return Boolean(\n target.closest(\n [\n 'button',\n 'a[href]',\n 'input',\n 'select',\n 'textarea:not(.rp-textarea__native)',\n '[contenteditable=\"true\"]',\n '[tabindex]:not([tabindex=\"-1\"])',\n ].join(','),\n ),\n );\n}\n\nexport function useTextarea(props: Readonly<TextareaProps>, emitUpdate: (value: string) => void) {\n const control = useControlState(props);\n\n const rootClass = computed(() =>\n bem('rp-textarea', {\n [`size-${props.size}`]: Boolean(props.size),\n [`radius-${props.radius}`]: Boolean(props.radius),\n disabled: control.disabled,\n invalid: control.invalid,\n valid: control.valid && !control.invalid,\n readonly: props.readonly,\n }),\n );\n\n function onInput(e: Event) {\n emitUpdate((e.target as HTMLTextAreaElement).value);\n }\n\n function focusTextarea(e: MouseEvent) {\n if (control.disabled) return;\n\n const target = e.target;\n if (target instanceof Element && isInteractiveElement(target)) return;\n\n (e.currentTarget as HTMLElement)\n .querySelector<HTMLTextAreaElement>('.rp-textarea__native')\n ?.focus();\n }\n\n return {\n control,\n rootClass,\n onInput,\n focusTextarea,\n };\n}\n","<template>\n <div :class=\"rootClass\" @mousedown=\"focusTextarea\">\n <textarea\n :id=\"control.id\"\n :name=\"name\"\n class=\"rp-textarea__native\"\n :value=\"modelValue\"\n :placeholder=\"placeholder\"\n :rows=\"rows\"\n :disabled=\"control.disabled || undefined\"\n :readonly=\"readonly || undefined\"\n :required=\"control.required || undefined\"\n :aria-label=\"ariaLabel || undefined\"\n :aria-labelledby=\"control.ariaLabelledby\"\n :aria-describedby=\"control.ariaDescribedby\"\n :aria-invalid=\"control.invalid || undefined\"\n :aria-required=\"control.required || undefined\"\n @input=\"onInput\"\n />\n </div>\n</template>\n\n<script lang=\"ts\" setup vapor>\nimport { useTextarea } from './useTextarea';\nimport type { TextareaProps } from './types';\n\ndefineOptions({ name: 'RpTextarea' });\n\nconst props = withDefaults(defineProps<TextareaProps>(), {\n placeholder: '',\n rows: 3,\n disabled: undefined,\n required: undefined,\n invalid: undefined,\n valid: undefined,\n readonly: false,\n});\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string];\n}>();\n\nconst { control, rootClass, onInput, focusTextarea } = useTextarea(props, (value) => {\n emit('update:modelValue', value);\n});\n</script>\n\n<style src=\"./textarea.scss\" lang=\"scss\" scoped></style>\n","<template>\n <div :class=\"rootClass\" @mousedown=\"focusTextarea\">\n <textarea\n :id=\"control.id\"\n :name=\"name\"\n class=\"rp-textarea__native\"\n :value=\"modelValue\"\n :placeholder=\"placeholder\"\n :rows=\"rows\"\n :disabled=\"control.disabled || undefined\"\n :readonly=\"readonly || undefined\"\n :required=\"control.required || undefined\"\n :aria-label=\"ariaLabel || undefined\"\n :aria-labelledby=\"control.ariaLabelledby\"\n :aria-describedby=\"control.ariaDescribedby\"\n :aria-invalid=\"control.invalid || undefined\"\n :aria-required=\"control.required || undefined\"\n @input=\"onInput\"\n />\n </div>\n</template>\n\n<script lang=\"ts\" setup vapor>\nimport { useTextarea } from './useTextarea';\nimport type { TextareaProps } from './types';\n\ndefineOptions({ name: 'RpTextarea' });\n\nconst props = withDefaults(defineProps<TextareaProps>(), {\n placeholder: '',\n rows: 3,\n disabled: undefined,\n required: undefined,\n invalid: undefined,\n valid: undefined,\n readonly: false,\n});\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string];\n}>();\n\nconst { control, rootClass, onInput, focusTextarea } = useTextarea(props, (value) => {\n emit('update:modelValue', value);\n});\n</script>\n\n<style src=\"./textarea.scss\" lang=\"scss\" scoped></style>\n"],"mappings":";;;;AAKA,SAAS,qBAAqB,QAAiB;CAC3C,OAAO,QACH,OAAO,QACH;EACI;EACA;EACA;EACA;EACA;EACA;EACA;CACJ,CAAC,CAAC,KAAK,GAAG,CACd,CACJ;AACJ;AAEA,SAAgB,YAAY,OAAgC,YAAqC;CAC7F,MAAM,UAAU,gBAAgB,KAAK;CAErC,MAAM,YAAY,eACd,IAAI,eAAe;GACd,QAAQ,MAAM,SAAS,QAAQ,MAAM,IAAI;GACzC,UAAU,MAAM,WAAW,QAAQ,MAAM,MAAM;EAChD,UAAU,QAAQ;EAClB,SAAS,QAAQ;EACjB,OAAO,QAAQ,SAAS,CAAC,QAAQ;EACjC,UAAU,MAAM;CACpB,CAAC,CACL;CAEA,SAAS,QAAQ,GAAU;EACvB,WAAY,EAAE,OAA+B,KAAK;CACtD;CAEA,SAAS,cAAc,GAAe;EAClC,IAAI,QAAQ,UAAU;EAEtB,MAAM,SAAS,EAAE;EACjB,IAAI,kBAAkB,WAAW,qBAAqB,MAAM,GAAG;EAE/D,EAAG,cACE,cAAmC,sBAAsB,CAAC,EACzD,MAAM;CAChB;CAEA,OAAO;EACH;EACA;EACA;EACA;CACJ;AACJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EC5BA,MAAM,QAAQ;EAUd,MAAM,OAAO;EAIb,MAAM,EAAE,SAAS,WAAW,SAAS,kBAAkB,YAAY,QAAQ,UAAU;GACjF,KAAK,qBAAqB,KAAK;EACnC,CAAC;;;sCA3BmB,MAAA,OAAA,CAAO,CAAA,CAAA,CAAA;0CAhBa,MAAA,aAAA,CAAa,CAAA,CAAA,CAAA;;;;gBAApC,MAAA,SAAA,CAAS;eAEb,MAAI,SAAO,EAAA;eACX,QAAM,QAAA,IAAI;gBAEH,QAAA,UAAU;eACjB,eAAa,QAAA,WAAW;eACxB,QAAM,QAAA,IAAI;eACV,YAAU,SAAO,YAAa,KAAA,CAAS;eACvC,YAAU,QAAA,YAAY,KAAA,CAAS;eAC/B,YAAU,qBAAoB,KAAA,CAAS;eACvC,cAAY,QAAA,aAAa,KAAA,CAAS;eAClC,mBAAiB,SAAO,cAAA;eACxB,oBAAkB,SAAO,eAAA;eACzB,gBAAc,SAAO,WAAY,KAAA,CAAS;eAC1C,iBAAe,qBAAoB,KAAA,CAAS"}
@@ -9,6 +9,7 @@ function useControlState(options = {}) {
9
9
  const disabled = computed(() => options.disabled ?? false);
10
10
  const required = computed(() => options.required ?? false);
11
11
  const invalid = computed(() => options.invalid ?? false);
12
+ const valid = computed(() => options.valid ?? false);
12
13
  const ariaDescribedby = computed(() => mergeIds(options.describedby));
13
14
  const ariaLabelledby = computed(() => mergeIds(options.labelledby));
14
15
  return {
@@ -24,6 +25,9 @@ function useControlState(options = {}) {
24
25
  get invalid() {
25
26
  return invalid.value;
26
27
  },
28
+ get valid() {
29
+ return valid.value;
30
+ },
27
31
  get ariaDescribedby() {
28
32
  return ariaDescribedby.value;
29
33
  },
@@ -1 +1 @@
1
- {"version":3,"file":"useControlState.js","names":[],"sources":["../src/composables/useControlState.ts"],"sourcesContent":["import { computed } from 'vue';\n\nexport interface ControlStateOptions {\n id?: string;\n disabled?: boolean;\n required?: boolean;\n invalid?: boolean;\n describedby?: string;\n labelledby?: string;\n}\n\nexport interface ControlState {\n id: string | undefined;\n disabled: boolean;\n required: boolean;\n invalid: boolean;\n ariaDescribedby: string | undefined;\n ariaLabelledby: string | undefined;\n}\n\nfunction mergeIds(...values: Array<string | undefined>): string | undefined {\n const ids = values\n .flatMap((value) => value?.split(/\\s+/) ?? [])\n .filter(Boolean);\n return ids.length > 0 ? Array.from(new Set(ids)).join(' ') : undefined;\n}\n\nexport function useControlState(options: ControlStateOptions = {}): ControlState {\n const id = computed(() => options.id);\n const disabled = computed(() => options.disabled ?? false);\n const required = computed(() => options.required ?? false);\n const invalid = computed(() => options.invalid ?? false);\n\n const ariaDescribedby = computed(() => mergeIds(options.describedby));\n const ariaLabelledby = computed(() => mergeIds(options.labelledby));\n\n return {\n get id() { return id.value; },\n get disabled() { return disabled.value; },\n get required() { return required.value; },\n get invalid() { return invalid.value; },\n get ariaDescribedby() { return ariaDescribedby.value; },\n get ariaLabelledby() { return ariaLabelledby.value; },\n };\n}\n"],"mappings":";;AAoBA,SAAS,SAAS,GAAG,QAAuD;CACxE,MAAM,MAAM,OACP,SAAS,UAAU,OAAO,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,CAC7C,OAAO,OAAO;CACnB,OAAO,IAAI,SAAS,IAAI,MAAM,KAAK,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,KAAA;AACjE;AAEA,SAAgB,gBAAgB,UAA+B,CAAC,GAAiB;CAC7E,MAAM,KAAK,eAAe,QAAQ,EAAE;CACpC,MAAM,WAAW,eAAe,QAAQ,YAAY,KAAK;CACzD,MAAM,WAAW,eAAe,QAAQ,YAAY,KAAK;CACzD,MAAM,UAAU,eAAe,QAAQ,WAAW,KAAK;CAEvD,MAAM,kBAAkB,eAAe,SAAS,QAAQ,WAAW,CAAC;CACpE,MAAM,iBAAiB,eAAe,SAAS,QAAQ,UAAU,CAAC;CAElE,OAAO;EACH,IAAI,KAAK;GAAE,OAAO,GAAG;EAAO;EAC5B,IAAI,WAAW;GAAE,OAAO,SAAS;EAAO;EACxC,IAAI,WAAW;GAAE,OAAO,SAAS;EAAO;EACxC,IAAI,UAAU;GAAE,OAAO,QAAQ;EAAO;EACtC,IAAI,kBAAkB;GAAE,OAAO,gBAAgB;EAAO;EACtD,IAAI,iBAAiB;GAAE,OAAO,eAAe;EAAO;CACxD;AACJ"}
1
+ {"version":3,"file":"useControlState.js","names":[],"sources":["../src/composables/useControlState.ts"],"sourcesContent":["import { computed } from 'vue';\n\nexport interface ControlStateOptions {\n id?: string;\n disabled?: boolean;\n required?: boolean;\n invalid?: boolean;\n valid?: boolean;\n describedby?: string;\n labelledby?: string;\n}\n\nexport interface ControlState {\n id: string | undefined;\n disabled: boolean;\n required: boolean;\n invalid: boolean;\n valid: boolean;\n ariaDescribedby: string | undefined;\n ariaLabelledby: string | undefined;\n}\n\nfunction mergeIds(...values: Array<string | undefined>): string | undefined {\n const ids = values.flatMap((value) => value?.split(/\\s+/) ?? []).filter(Boolean);\n return ids.length > 0 ? Array.from(new Set(ids)).join(' ') : undefined;\n}\n\nexport function useControlState(options: ControlStateOptions = {}): ControlState {\n const id = computed(() => options.id);\n const disabled = computed(() => options.disabled ?? false);\n const required = computed(() => options.required ?? false);\n const invalid = computed(() => options.invalid ?? false);\n const valid = computed(() => options.valid ?? false);\n\n const ariaDescribedby = computed(() => mergeIds(options.describedby));\n const ariaLabelledby = computed(() => mergeIds(options.labelledby));\n\n return {\n get id() {\n return id.value;\n },\n get disabled() {\n return disabled.value;\n },\n get required() {\n return required.value;\n },\n get invalid() {\n return invalid.value;\n },\n get valid() {\n return valid.value;\n },\n get ariaDescribedby() {\n return ariaDescribedby.value;\n },\n get ariaLabelledby() {\n return ariaLabelledby.value;\n },\n };\n}\n"],"mappings":";;AAsBA,SAAS,SAAS,GAAG,QAAuD;CACxE,MAAM,MAAM,OAAO,SAAS,UAAU,OAAO,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,OAAO;CAC/E,OAAO,IAAI,SAAS,IAAI,MAAM,KAAK,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,KAAA;AACjE;AAEA,SAAgB,gBAAgB,UAA+B,CAAC,GAAiB;CAC7E,MAAM,KAAK,eAAe,QAAQ,EAAE;CACpC,MAAM,WAAW,eAAe,QAAQ,YAAY,KAAK;CACzD,MAAM,WAAW,eAAe,QAAQ,YAAY,KAAK;CACzD,MAAM,UAAU,eAAe,QAAQ,WAAW,KAAK;CACvD,MAAM,QAAQ,eAAe,QAAQ,SAAS,KAAK;CAEnD,MAAM,kBAAkB,eAAe,SAAS,QAAQ,WAAW,CAAC;CACpE,MAAM,iBAAiB,eAAe,SAAS,QAAQ,UAAU,CAAC;CAElE,OAAO;EACH,IAAI,KAAK;GACL,OAAO,GAAG;EACd;EACA,IAAI,WAAW;GACX,OAAO,SAAS;EACpB;EACA,IAAI,WAAW;GACX,OAAO,SAAS;EACpB;EACA,IAAI,UAAU;GACV,OAAO,QAAQ;EACnB;EACA,IAAI,QAAQ;GACR,OAAO,MAAM;EACjB;EACA,IAAI,kBAAkB;GAClB,OAAO,gBAAgB;EAC3B;EACA,IAAI,iBAAiB;GACjB,OAAO,eAAe;EAC1B;CACJ;AACJ"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ropav",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "type": "module",
5
5
  "packageManager": "pnpm@11.9.0",
6
6
  "engines": {
@@ -45,18 +45,10 @@
45
45
  "types": "./dist/components/switch/index.d.ts",
46
46
  "import": "./dist/components/switch/index.js"
47
47
  },
48
- "./tabs": {
49
- "types": "./dist/components/tabs/index.d.ts",
50
- "import": "./dist/components/tabs/index.js"
51
- },
52
48
  "./textarea": {
53
49
  "types": "./dist/components/textarea/index.d.ts",
54
50
  "import": "./dist/components/textarea/index.js"
55
51
  },
56
- "./tooltip": {
57
- "types": "./dist/components/tooltip/index.d.ts",
58
- "import": "./dist/components/tooltip/index.js"
59
- },
60
52
  "./base.css": "./dist/base.css",
61
53
  "./scss/*": "./src/styles/*"
62
54
  },
@@ -66,6 +58,10 @@
66
58
  "tokens:check": "node scripts/check-tokens.mjs",
67
59
  "typecheck": "vue-tsc -b tsconfig.app.json tsconfig.node.json",
68
60
  "typecheck:storybook": "vue-tsc -p tsconfig.storybook.json --noEmit",
61
+ "lint": "oxlint",
62
+ "lint:fix": "oxlint --fix",
63
+ "format": "oxfmt",
64
+ "format:check": "oxfmt --check",
69
65
  "test": "vitest run --project=unit",
70
66
  "test:exports": "node scripts/check-exports.mjs",
71
67
  "test:watch": "vitest --project=unit",
@@ -83,6 +79,7 @@
83
79
  "vue": "^3.6.0-beta.4"
84
80
  },
85
81
  "devDependencies": {
82
+ "@iconify-json/lucide": "^1.2.116",
86
83
  "@storybook/addon-themes": "^10.4.6",
87
84
  "@storybook/addon-vitest": "^10.4.6",
88
85
  "@storybook/vue3-vite": "^10.4.6",
@@ -92,11 +89,14 @@
92
89
  "@vue/tsconfig": "^0.9.1",
93
90
  "bumpp": "^11.1.0",
94
91
  "jsdom": "^29.1.1",
92
+ "oxfmt": "^0.57.0",
93
+ "oxlint": "^1.72.0",
95
94
  "playwright": "^1.61.1",
96
95
  "sass-embedded": "^1.100.0",
97
96
  "storybook": "^10.4.6",
98
97
  "style-dictionary": "5.5.0",
99
98
  "typescript": "~6.0.3",
99
+ "unplugin-icons": "^23.0.1",
100
100
  "vite": "^8.1.3",
101
101
  "vite-plugin-dts": "^5.0.3",
102
102
  "vitest": "^4.1.9",
@@ -1,3 +1,5 @@
1
+ @use 'variables' as *;
2
+
1
3
  @mixin flex-center {
2
4
  display: inline-flex;
3
5
  align-items: center;
@@ -5,7 +7,7 @@
5
7
  }
6
8
 
7
9
  @mixin focus-ring {
8
- border-color: var(--rp-color-control-border-focus);
10
+ border-color: var(--rp-color-primary);
9
11
  box-shadow: 0 0 0 var(--rp-border-width-medium) var(--rp-color-focus-ring);
10
12
  }
11
13
 
@@ -75,7 +77,11 @@
75
77
  }
76
78
  }
77
79
 
78
- @mixin menu-surface($z-index: var(--rp-z-index-dropdown), $surface: var(--rp-color-surface-raised), $radius: var(--rp-radius-lg)) {
80
+ @mixin menu-surface(
81
+ $z-index: $z-index-dropdown,
82
+ $surface: var(--rp-color-surface-raised),
83
+ $radius: var(--rp-radius-lg)
84
+ ) {
79
85
  z-index: $z-index;
80
86
  background-color: $surface;
81
87
  border: var(--rp-border-width-thin) solid var(--rp-color-border);
@@ -99,7 +105,9 @@
99
105
 
100
106
  @mixin semantic-colors($var-name) {
101
107
  @each $name in primary, secondary, success, warning, danger, info {
102
- &--#{$name} { #{$var-name}: var(--rp-color-#{$name}-fg); }
108
+ &--#{$name} {
109
+ #{$var-name}: var(--rp-color-#{$name}-fg);
110
+ }
103
111
  }
104
112
  }
105
113
 
@@ -116,11 +124,13 @@
116
124
  @each $name in primary, secondary, success, warning, danger, info {
117
125
  &--#{$name} {
118
126
  #{$prefix}-bg: var(--rp-color-#{$name});
119
- #{$prefix}-bg-hover: color-mix(in srgb, var(--rp-color-#{$name}) 90%, var(--rp-color-black));
120
- #{$prefix}-bg-active: color-mix(in srgb, var(--rp-color-#{$name}) 80%, var(--rp-color-black));
121
- #{$prefix}-subtle-bg: color-mix(in srgb, var(--rp-color-#{$name}) 10%, transparent);
122
- #{$prefix}-subtle-bg-hover: color-mix(in srgb, var(--rp-color-#{$name}) 14%, transparent);
123
- #{$prefix}-subtle-bg-active: color-mix(in srgb, var(--rp-color-#{$name}) 18%, transparent);
127
+ #{$prefix}-bg-hover: var(--rp-color-#{$name}-hover);
128
+ #{$prefix}-bg-active: var(--rp-color-#{$name}-active);
129
+ #{$prefix}-subtle-bg: var(--rp-color-#{$name}-subtle-bg);
130
+ #{$prefix}-subtle-bg-hover: var(--rp-color-#{$name}-subtle-bg-hover);
131
+ #{$prefix}-subtle-bg-active: var(--rp-color-#{$name}-subtle-bg-active);
132
+ #{$prefix}-border: var(--rp-color-#{$name}-border);
133
+ #{$prefix}-border-hover: var(--rp-color-#{$name}-border-hover);
124
134
  #{$prefix}-fg: var(--rp-color-#{$name}-fg);
125
135
  #{$prefix}-on-bg: var(--rp-color-on-#{$name});
126
136
  }