origam 2.7.3 → 2.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +83 -0
  3. package/dist/src/components/Alert/OrigamAlert.vue +4 -0
  4. package/dist/src/components/App/OrigamAppBar.vue +4 -0
  5. package/dist/src/components/Audio/OrigamAudio.vue +4 -0
  6. package/dist/src/components/Avatar/OrigamAvatar.vue +4 -0
  7. package/dist/src/components/Avatar/OrigamAvatarGroup.vue +4 -0
  8. package/dist/src/components/Badge/OrigamBadge.vue +4 -0
  9. package/dist/src/components/Blockquote/OrigamBlockquote.vue +18 -5
  10. package/dist/src/components/BottomNav/OrigamBottomNav.vue +4 -0
  11. package/dist/src/components/Bracket/OrigamBracket.vue +4 -0
  12. package/dist/src/components/Bracket/OrigamBracketCompetitor.vue +4 -0
  13. package/dist/src/components/Bracket/OrigamBracketMatch.vue +4 -0
  14. package/dist/src/components/Breadcrumb/OrigamBreadcrumb.vue +4 -0
  15. package/dist/src/components/Breadcrumb/OrigamBreadcrumbItem.vue +4 -0
  16. package/dist/src/components/Btn/OrigamBtn.vue +4 -0
  17. package/dist/src/components/Btn/OrigamBtnGroup.vue +4 -0
  18. package/dist/src/components/Btn/OrigamBtnToggle.vue +4 -0
  19. package/dist/src/components/Calendar/OrigamCalendar.vue +4 -0
  20. package/dist/src/components/Card/OrigamCard.vue +4 -0
  21. package/dist/src/components/Card/OrigamCardHeader.vue +4 -0
  22. package/dist/src/components/Card/OrigamCardText.vue +4 -0
  23. package/dist/src/components/Carousel/OrigamCarousel.vue +4 -0
  24. package/dist/src/components/Carousel/OrigamCarouselItem.vue +4 -0
  25. package/dist/src/components/Checkbox/OrigamCheckbox.vue +4 -0
  26. package/dist/src/components/Chip/OrigamChip.vue +4 -0
  27. package/dist/src/components/Chip/OrigamChipGroup.vue +4 -0
  28. package/dist/src/components/Clipboard/OrigamClipboard.vue +4 -0
  29. package/dist/src/components/Code/OrigamCode.vue +4 -0
  30. package/dist/src/components/ColorPicker/OrigamColorPicker.vue +4 -0
  31. package/dist/src/components/ColorPickerField/OrigamColorPickerField.vue +4 -0
  32. package/dist/src/components/ContextualMenu/OrigamContextualMenu.vue +4 -0
  33. package/dist/src/components/Counter/OrigamCounter.vue +4 -0
  34. package/dist/src/components/DataList/OrigamDataList.vue +4 -0
  35. package/dist/src/components/DataTable/OrigamDataTable.vue +4 -0
  36. package/dist/src/components/DatePicker/OrigamDatePicker.vue +4 -0
  37. package/dist/src/components/DatePickerField/OrigamDatePickerField.vue +4 -0
  38. package/dist/src/components/Dialog/OrigamDialog.vue +4 -0
  39. package/dist/src/components/Dialog/OrigamDialogConfirmation.vue +4 -0
  40. package/dist/src/components/Drawer/OrigamDrawer.vue +4 -0
  41. package/dist/src/components/ExpansionPanel/OrigamExpansionPanel.vue +4 -0
  42. package/dist/src/components/ExpansionPanel/OrigamExpansionPanelContent.vue +4 -0
  43. package/dist/src/components/ExpansionPanel/OrigamExpansionPanelHeader.vue +4 -0
  44. package/dist/src/components/ExpansionPanel/OrigamExpansionPanels.vue +4 -0
  45. package/dist/src/components/Field/OrigamField.vue +4 -0
  46. package/dist/src/components/FileField/OrigamFileField.vue +4 -0
  47. package/dist/src/components/Grid/OrigamGrid.vue +5 -1
  48. package/dist/src/components/Grids/OrigamCol.vue +4 -0
  49. package/dist/src/components/Grids/OrigamContainer.vue +5 -1
  50. package/dist/src/components/Grids/OrigamRow.vue +4 -0
  51. package/dist/src/components/Icon/OrigamClassIcon.vue +4 -0
  52. package/dist/src/components/Icon/OrigamComponentIcon.vue +4 -0
  53. package/dist/src/components/Icon/OrigamIcon.vue +4 -0
  54. package/dist/src/components/Icon/OrigamLigatureIcon.vue +4 -0
  55. package/dist/src/components/Icon/OrigamSvgIcon.vue +4 -0
  56. package/dist/src/components/Img/OrigamImg.vue +4 -0
  57. package/dist/src/components/Input/OrigamInput.vue +4 -0
  58. package/dist/src/components/Kbd/OrigamKbd.vue +4 -0
  59. package/dist/src/components/Label/OrigamLabel.vue +4 -0
  60. package/dist/src/components/Layout/OrigamLayout.vue +5 -1
  61. package/dist/src/components/List/OrigamList.vue +4 -0
  62. package/dist/src/components/List/OrigamListGroup.vue +4 -0
  63. package/dist/src/components/List/OrigamListItem.vue +4 -0
  64. package/dist/src/components/List/OrigamListSubheader.vue +4 -0
  65. package/dist/src/components/Main/OrigamMain.vue +4 -0
  66. package/dist/src/components/Masonry/OrigamMasonry.vue +5 -1
  67. package/dist/src/components/Menu/OrigamMenu.vue +4 -0
  68. package/dist/src/components/Messages/OrigamMessages.vue +4 -0
  69. package/dist/src/components/NumberField/OrigamNumberField.vue +4 -0
  70. package/dist/src/components/OtpInputField/OrigamOtpInputField.vue +4 -0
  71. package/dist/src/components/Pagination/OrigamPagination.vue +4 -0
  72. package/dist/src/components/Parallax/OrigamParallax.vue +4 -0
  73. package/dist/src/components/Parallax/OrigamParallaxElement.vue +4 -0
  74. package/dist/src/components/PasswordField/OrigamPasswordField.vue +4 -0
  75. package/dist/src/components/Picker/OrigamPicker.vue +4 -0
  76. package/dist/src/components/QrCode/OrigamQrCode.vue +4 -0
  77. package/dist/src/components/Radio/OrigamRadio.vue +4 -0
  78. package/dist/src/components/Radio/OrigamRadioGroup.vue +4 -0
  79. package/dist/src/components/RatingField/OrigamRatingField.vue +4 -0
  80. package/dist/src/components/RatingField/OrigamRatingFieldItem.vue +4 -0
  81. package/dist/src/components/Responsive/OrigamResponsive.vue +4 -0
  82. package/dist/src/components/Select/OrigamSelect.vue +4 -0
  83. package/dist/src/components/Sheet/OrigamSheet.vue +4 -0
  84. package/dist/src/components/Slide/OrigamSlideGroup.vue +4 -0
  85. package/dist/src/components/SliderField/OrigamSliderField.vue +4 -0
  86. package/dist/src/components/Snackbar/OrigamSnackbar.vue +4 -0
  87. package/dist/src/components/Stepper/OrigamStepper.vue +5 -1
  88. package/dist/src/components/Switch/OrigamSwitch.vue +4 -0
  89. package/dist/src/components/SystemBar/OrigamSystemBar.vue +4 -0
  90. package/dist/src/components/Table/OrigamTable.vue +4 -0
  91. package/dist/src/components/TextField/OrigamTextField.vue +4 -0
  92. package/dist/src/components/TextareaField/OrigamTextareaField.vue +4 -0
  93. package/dist/src/components/Title/OrigamTitle.vue +4 -0
  94. package/dist/src/components/Toolbar/OrigamToolbar.vue +4 -0
  95. package/dist/src/components/Video/OrigamVideo.vue +4 -0
  96. package/dist/src/components/Window/OrigamWindow.vue +4 -0
  97. package/dist/src/composables/Commons/border.composable.cjs +22 -0
  98. package/dist/src/composables/Commons/border.composable.d.ts +19 -0
  99. package/dist/src/composables/Commons/border.composable.js +28 -2
  100. package/dist/src/composables/Commons/elevation.composable.cjs +5 -1
  101. package/dist/src/composables/Commons/elevation.composable.d.ts +14 -3
  102. package/dist/src/composables/Commons/elevation.composable.js +6 -2
  103. package/dist/src/composables/Commons/stateEffect.composable.cjs +24 -0
  104. package/dist/src/composables/Commons/stateEffect.composable.js +24 -0
  105. package/dist/src/consts/Commons/border.const.cjs +20 -2
  106. package/dist/src/consts/Commons/border.const.d.ts +29 -0
  107. package/dist/src/consts/Commons/border.const.js +7 -0
  108. package/dist/src/consts/Commons/elevation.const.cjs +3 -2
  109. package/dist/src/consts/Commons/elevation.const.d.ts +20 -0
  110. package/dist/src/consts/Commons/elevation.const.js +1 -0
  111. package/dist/src/interfaces/Blockquote/blockquote.interface.d.ts +15 -8
  112. package/dist/src/interfaces/Commons/border.interface.d.ts +20 -1
  113. package/dist/src/interfaces/Commons/color.interface.d.ts +24 -0
  114. package/dist/src/interfaces/Commons/elevation.interface.d.ts +2 -1
  115. package/dist/src/types/Commons/elevation.type.cjs +1 -0
  116. package/dist/src/types/Commons/elevation.type.d.ts +20 -0
  117. package/dist/src/types/Commons/elevation.type.js +0 -0
  118. package/dist/src/types/index.cjs +11 -0
  119. package/dist/src/types/index.d.ts +1 -0
  120. package/dist/src/types/index.js +1 -0
  121. package/dist/src/utils/Commons/border.util.cjs +36 -0
  122. package/dist/src/utils/Commons/border.util.d.ts +59 -0
  123. package/dist/src/utils/Commons/border.util.js +29 -0
  124. package/dist/src/utils/Commons/color.util.cjs +9 -0
  125. package/dist/src/utils/Commons/color.util.d.ts +7 -0
  126. package/dist/src/utils/Commons/color.util.js +10 -0
  127. package/dist/src/utils/Commons/elevation.util.cjs +5 -0
  128. package/dist/src/utils/Commons/elevation.util.d.ts +10 -0
  129. package/dist/src/utils/Commons/elevation.util.js +4 -0
  130. package/dist/src/utils/Commons/margin.util.cjs +4 -0
  131. package/dist/src/utils/Commons/margin.util.d.ts +23 -1
  132. package/dist/src/utils/Commons/margin.util.js +4 -0
  133. package/dist/src/utils/Commons/padding.util.d.ts +23 -1
  134. package/package.json +1 -1
@@ -51,6 +51,10 @@ const props = defineProps({
51
51
  borderInline: { type: [Boolean, Number, String], required: false },
52
52
  borderColor: { type: String, required: false },
53
53
  borderStyle: { type: String, required: false },
54
+ borderTopColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
55
+ borderRightColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
56
+ borderBottomColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
57
+ borderLeftColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
54
58
  height: { type: [Number, String], required: false },
55
59
  maxHeight: { type: [Number, String], required: false },
56
60
  maxWidth: { type: [Number, String], required: false },
@@ -58,6 +58,10 @@ const props = defineProps({
58
58
  borderInline: { type: [Boolean, Number, String], required: false },
59
59
  borderColor: { type: String, required: false },
60
60
  borderStyle: { type: String, required: false },
61
+ borderTopColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
62
+ borderRightColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
63
+ borderBottomColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
64
+ borderLeftColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
61
65
  rounded: { type: [Boolean, Number, String, null], required: false, skipCheck: true },
62
66
  roundedTopRight: { type: [Boolean, Number, String], required: false },
63
67
  roundedTopLeft: { type: [Boolean, Number, String], required: false },
@@ -270,6 +270,10 @@ const _props = defineProps({
270
270
  borderInline: { type: [Boolean, Number, String], required: false },
271
271
  borderColor: { type: String, required: false },
272
272
  borderStyle: { type: String, required: false },
273
+ borderTopColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
274
+ borderRightColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
275
+ borderBottomColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
276
+ borderLeftColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
273
277
  rounded: { type: [Boolean, Number, String, null], required: false, skipCheck: true, default: true },
274
278
  roundedTopRight: { type: [Boolean, Number, String], required: false },
275
279
  roundedTopLeft: { type: [Boolean, Number, String], required: false },
@@ -362,6 +362,10 @@ const _props = defineProps({
362
362
  borderInline: { type: [Boolean, Number, String], required: false },
363
363
  borderColor: { type: String, required: false },
364
364
  borderStyle: { type: String, required: false },
365
+ borderTopColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
366
+ borderRightColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
367
+ borderBottomColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
368
+ borderLeftColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
365
369
  rounded: { type: [Boolean, Number, String, null], required: false, skipCheck: true, default: true },
366
370
  roundedTopRight: { type: [Boolean, Number, String], required: false },
367
371
  roundedTopLeft: { type: [Boolean, Number, String], required: false },
@@ -60,6 +60,10 @@ const props = defineProps({
60
60
  borderInline: { type: [Boolean, Number, String], required: false },
61
61
  borderColor: { type: String, required: false },
62
62
  borderStyle: { type: String, required: false },
63
+ borderTopColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
64
+ borderRightColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
65
+ borderBottomColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
66
+ borderLeftColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
63
67
  fontFamily: { type: String, required: false },
64
68
  fontSize: { type: String, required: false },
65
69
  fontWeight: { type: String, required: false },
@@ -72,6 +72,10 @@ const props = defineProps({
72
72
  borderInline: { type: [Boolean, Number, String], required: false },
73
73
  borderColor: { type: String, required: false },
74
74
  borderStyle: { type: String, required: false },
75
+ borderTopColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
76
+ borderRightColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
77
+ borderBottomColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
78
+ borderLeftColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
75
79
  rounded: { type: [Boolean, Number, String, null], required: false, skipCheck: true },
76
80
  roundedTopRight: { type: [Boolean, Number, String], required: false },
77
81
  roundedTopLeft: { type: [Boolean, Number, String], required: false },
@@ -279,6 +279,10 @@ const props = defineProps({
279
279
  borderInline: { type: [Boolean, Number, String], required: false },
280
280
  borderColor: { type: String, required: false },
281
281
  borderStyle: { type: String, required: false },
282
+ borderTopColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
283
+ borderRightColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
284
+ borderBottomColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
285
+ borderLeftColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
282
286
  margin: { type: [Boolean, Number, String], required: false },
283
287
  marginTop: { type: [Boolean, Number, String], required: false },
284
288
  marginLeft: { type: [Boolean, Number, String], required: false },
@@ -103,6 +103,10 @@ const props = defineProps({
103
103
  borderInline: { type: [Boolean, Number, String], required: false },
104
104
  borderColor: { type: String, required: false },
105
105
  borderStyle: { type: String, required: false },
106
+ borderTopColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
107
+ borderRightColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
108
+ borderBottomColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
109
+ borderLeftColor: { type: [String, Object, Boolean, null], required: false, skipCheck: true },
106
110
  padding: { type: [Boolean, Number, String], required: false },
107
111
  paddingTop: { type: [Boolean, Number, String], required: false },
108
112
  paddingLeft: { type: [Boolean, Number, String], required: false },
@@ -53,6 +53,28 @@ function useBorder(props, name = (0, _utils.getCurrentInstanceName)()) {
53
53
  } = props;
54
54
  if (!(0, _utils.isEmpty)(borderColor)) styles.push(`border-color: ${borderColor}`);
55
55
  if (!(0, _utils.isEmpty)(borderStyle)) styles.push(`border-style: ${borderStyle}`);
56
+ _consts.BORDER_POSITION_MAP.forEach(({
57
+ side,
58
+ widthProp,
59
+ colorProp
60
+ }) => {
61
+ const sideValue = props[widthProp];
62
+ const sideColor = props[colorProp];
63
+ if (typeof sideValue === "number") {
64
+ styles.push(`border-${side}-width: ${(0, _utils.convertToUnit)(sideValue)}`);
65
+ styles.push(`border-${side}-style: solid`);
66
+ styles.push(`border-${side}-color: currentColor`);
67
+ } else if (sideValue === true) {
68
+ styles.push(`border-${side}-width: var(--origam-border__width---thin)`);
69
+ styles.push(`border-${side}-style: solid`);
70
+ styles.push(`border-${side}-color: currentColor`);
71
+ } else if (typeof sideValue === "string" && sideValue !== "") {
72
+ const parsed = (0, _utils.parseBorderPositionValue)(sideValue);
73
+ if (parsed) styles.push(...(0, _utils.formatBorderPositionStylesVar)(side, parsed));
74
+ }
75
+ const resolvedSideColor = (0, _utils.resolveBorderSideColor)(sideColor);
76
+ if (resolvedSideColor) styles.push(`border-${side}-color: ${resolvedSideColor}`);
77
+ });
56
78
  }
57
79
  return styles;
58
80
  });
@@ -3,6 +3,25 @@ import type { IBorderProps } from '../../interfaces';
3
3
  import { TDirectionBoth } from "../../types";
4
4
  /*********************************************************
5
5
  * useBorder
6
+ *
7
+ * @description
8
+ * Precedence rule (issue #215) — SPECIFIC beats GLOBAL, always in this
9
+ * order, enforced purely by PUSH ORDER onto the `styles` array (later
10
+ * declarations win within the same inline `style` attribute — this holds
11
+ * even across logical vs physical property syntax for the same box edge):
12
+ *
13
+ * 1. global `border` shorthand (1/2/4-value, logical properties)
14
+ * 2. global standalone `borderColor` / `borderStyle`
15
+ * 3. per-side `borderTop` / `borderRight` / `borderBottom` / `borderLeft`
16
+ * (physical properties — width, and style/color when a full string
17
+ * like `"2px dashed red"` is given)
18
+ * 4. per-side `borderTopColor` / `borderRightColor` /
19
+ * `borderBottomColor` / `borderLeftColor`
20
+ *
21
+ * So `borderTop` beats `border` for the top side, and `borderTopColor`
22
+ * beats both the color embedded in `borderTop` and the global
23
+ * `borderColor` — each rung only overrides the physical side(s) it
24
+ * actually targets, everything else keeps cascading from the rung below.
6
25
  ********************************************************/
7
26
  export declare function useBorder(props: IBorderProps | Ref<boolean | number | string | TDirectionBoth | Array<TDirectionBoth> | null | undefined>, name?: string): {
8
27
  borderClasses: import("vue").ComputedRef<string[]>;
@@ -1,6 +1,14 @@
1
1
  import { computed, isRef } from "vue";
2
- import { BORDER_REGEX, DIRECTION_ARRAY } from "../../consts/index.js";
3
- import { convertToUnit, formatBorderStylesVar, getCurrentInstanceName, isEmpty } from "../../utils/index.js";
2
+ import { BORDER_POSITION_MAP, BORDER_REGEX, DIRECTION_ARRAY } from "../../consts/index.js";
3
+ import {
4
+ convertToUnit,
5
+ formatBorderPositionStylesVar,
6
+ formatBorderStylesVar,
7
+ getCurrentInstanceName,
8
+ isEmpty,
9
+ parseBorderPositionValue,
10
+ resolveBorderSideColor
11
+ } from "../../utils/index.js";
4
12
  const UTILITY_BORDER = /* @__PURE__ */ new Set([
5
13
  "none",
6
14
  "thin",
@@ -48,6 +56,24 @@ export function useBorder(props, name = getCurrentInstanceName()) {
48
56
  const { borderColor, borderStyle } = props;
49
57
  if (!isEmpty(borderColor)) styles.push(`border-color: ${borderColor}`);
50
58
  if (!isEmpty(borderStyle)) styles.push(`border-style: ${borderStyle}`);
59
+ BORDER_POSITION_MAP.forEach(({ side, widthProp, colorProp }) => {
60
+ const sideValue = props[widthProp];
61
+ const sideColor = props[colorProp];
62
+ if (typeof sideValue === "number") {
63
+ styles.push(`border-${side}-width: ${convertToUnit(sideValue)}`);
64
+ styles.push(`border-${side}-style: solid`);
65
+ styles.push(`border-${side}-color: currentColor`);
66
+ } else if (sideValue === true) {
67
+ styles.push(`border-${side}-width: var(--origam-border__width---thin)`);
68
+ styles.push(`border-${side}-style: solid`);
69
+ styles.push(`border-${side}-color: currentColor`);
70
+ } else if (typeof sideValue === "string" && sideValue !== "") {
71
+ const parsed = parseBorderPositionValue(sideValue);
72
+ if (parsed) styles.push(...formatBorderPositionStylesVar(side, parsed));
73
+ }
74
+ const resolvedSideColor = resolveBorderSideColor(sideColor);
75
+ if (resolvedSideColor) styles.push(`border-${side}-color: ${resolvedSideColor}`);
76
+ });
51
77
  }
52
78
  return styles;
53
79
  });
@@ -42,7 +42,7 @@ function useElevation(props, flat = (0, _vue.ref)(false), bgColor = (0, _vue.ref
42
42
  classes.push(`${name}--elevated`);
43
43
  if (isUtilityRung(elevation)) {
44
44
  classes.push(`origam--shadow-${elevation}`);
45
- } else if (!isOrigamRung(elevation)) {
45
+ } else if (!isOrigamRung(elevation) && !(typeof elevation === "string" && (0, _utils.isCustomBoxShadow)(elevation))) {
46
46
  const numeric = typeof elevation === "string" ? parseInt(elevation, 10) : elevation;
47
47
  if (typeof numeric === "number" && !Number.isNaN(numeric)) {
48
48
  const tokenName = elevationToToken(numeric);
@@ -61,6 +61,10 @@ function useElevation(props, flat = (0, _vue.ref)(false), bgColor = (0, _vue.ref
61
61
  styles.push(`box-shadow: var(--origam-shadow---${elevation})`);
62
62
  return styles;
63
63
  }
64
+ if (typeof elevation === "string" && (0, _utils.isCustomBoxShadow)(elevation)) {
65
+ styles.push(`box-shadow: ${elevation.trim()}`);
66
+ return styles;
67
+ }
64
68
  const numeric = typeof elevation === "string" ? parseInt(elevation, 10) : elevation;
65
69
  if (Number.isNaN(numeric)) return styles;
66
70
  const tokenName = elevationToToken(numeric);
@@ -1,19 +1,30 @@
1
1
  import { Ref } from 'vue';
2
2
  import type { IElevationProps } from '../../interfaces';
3
- import { TColor } from "../../types";
3
+ import { TColor, TElevation } from "../../types";
4
4
  /**
5
5
  * `useElevation` — refactored to consume design tokens (Lot 1).
6
6
  *
7
+ * Accepts three shapes for `elevation` (see `TElevation`):
8
+ * - an origam-native rung name (`'none'|'xs'|'sm'|'md'|'lg'|'xl'|'2xl'|'3xl'`),
9
+ * - a Material-style number `0..24` (as a `number` or numeric `string`),
10
+ * - a free-form custom `box-shadow` value (`'0 4px 12px rgba(0,0,0,.24)'`,
11
+ * `'var(--origam-shadow---card)'`, `'inset 0 0 0 2px #fff'`, …) —
12
+ * emitted verbatim via `elevationStyles`. Detected by `isCustomBoxShadow`
13
+ * (permissive signal-based check, same approach as `useRounded`'s
14
+ * `isCustomBorderRadius`), so genuinely invalid input keeps the
15
+ * pre-existing silent-drop behaviour (no regression).
16
+ *
7
17
  * Backward-compat:
8
18
  * - The signature is preserved (`bgColor` accepted but ignored).
9
19
  * - Returns the same shape: `{ elevationClasses, elevationStyles }`.
10
20
  * - `elevationStyles` is still a string array — emits a single `box-shadow:`
11
- * declaration that references the appropriate `--origam-shadow-*` token.
21
+ * declaration that references the appropriate `--origam-shadow-*` token,
22
+ * or the custom value verbatim.
12
23
  */
13
24
  /*********************************************************
14
25
  * useElevation
15
26
  ********************************************************/
16
- export declare function useElevation(props: IElevationProps | Ref<number | string | undefined>, flat?: Ref<boolean>, bgColor?: Ref<TColor>, name?: string): {
27
+ export declare function useElevation(props: IElevationProps | Ref<TElevation | undefined>, flat?: Ref<boolean>, bgColor?: Ref<TColor>, name?: string): {
17
28
  elevationClasses: import("vue").ComputedRef<string[]>;
18
29
  elevationStyles: import("vue").ComputedRef<string[]>;
19
30
  };
@@ -1,6 +1,6 @@
1
1
  import { computed, isRef, ref } from "vue";
2
2
  import { ORIGAM_SHADOW_RUNGS, UTILITY_SHADOW_RUNGS } from "../../consts/Commons/elevation.const.js";
3
- import { getCurrentInstanceName } from "../../utils/index.js";
3
+ import { getCurrentInstanceName, isCustomBoxShadow } from "../../utils/index.js";
4
4
  function elevationToToken(level) {
5
5
  if (level <= 0) return "none";
6
6
  if (level <= 1) return "xs";
@@ -36,7 +36,7 @@ export function useElevation(props, flat = ref(false), bgColor = ref("rgb(0,0,0)
36
36
  classes.push(`${name}--elevated`);
37
37
  if (isUtilityRung(elevation)) {
38
38
  classes.push(`origam--shadow-${elevation}`);
39
- } else if (!isOrigamRung(elevation)) {
39
+ } else if (!isOrigamRung(elevation) && !(typeof elevation === "string" && isCustomBoxShadow(elevation))) {
40
40
  const numeric = typeof elevation === "string" ? parseInt(elevation, 10) : elevation;
41
41
  if (typeof numeric === "number" && !Number.isNaN(numeric)) {
42
42
  const tokenName = elevationToToken(numeric);
@@ -55,6 +55,10 @@ export function useElevation(props, flat = ref(false), bgColor = ref("rgb(0,0,0)
55
55
  styles.push(`box-shadow: var(--origam-shadow---${elevation})`);
56
56
  return styles;
57
57
  }
58
+ if (typeof elevation === "string" && isCustomBoxShadow(elevation)) {
59
+ styles.push(`box-shadow: ${elevation.trim()}`);
60
+ return styles;
61
+ }
58
62
  const numeric = typeof elevation === "string" ? parseInt(elevation, 10) : elevation;
59
63
  if (Number.isNaN(numeric)) return styles;
60
64
  const tokenName = elevationToToken(numeric);
@@ -109,6 +109,30 @@ function useStateEffect(props, isHover = noopRef, isActive = noopRef, hoverState
109
109
  },
110
110
  get borderStyle() {
111
111
  return props.borderStyle;
112
+ },
113
+ get borderTop() {
114
+ return props.borderTop;
115
+ },
116
+ get borderRight() {
117
+ return props.borderRight;
118
+ },
119
+ get borderBottom() {
120
+ return props.borderBottom;
121
+ },
122
+ get borderLeft() {
123
+ return props.borderLeft;
124
+ },
125
+ get borderTopColor() {
126
+ return props.borderTopColor;
127
+ },
128
+ get borderRightColor() {
129
+ return props.borderRightColor;
130
+ },
131
+ get borderBottomColor() {
132
+ return props.borderBottomColor;
133
+ },
134
+ get borderLeftColor() {
135
+ return props.borderLeftColor;
112
136
  }
113
137
  }));
114
138
  const {
@@ -120,6 +120,30 @@ export function useStateEffect(props, isHover = noopRef, isActive = noopRef, hov
120
120
  },
121
121
  get borderStyle() {
122
122
  return props.borderStyle;
123
+ },
124
+ get borderTop() {
125
+ return props.borderTop;
126
+ },
127
+ get borderRight() {
128
+ return props.borderRight;
129
+ },
130
+ get borderBottom() {
131
+ return props.borderBottom;
132
+ },
133
+ get borderLeft() {
134
+ return props.borderLeft;
135
+ },
136
+ get borderTopColor() {
137
+ return props.borderTopColor;
138
+ },
139
+ get borderRightColor() {
140
+ return props.borderRightColor;
141
+ },
142
+ get borderBottomColor() {
143
+ return props.borderBottomColor;
144
+ },
145
+ get borderLeftColor() {
146
+ return props.borderLeftColor;
123
147
  }
124
148
  })
125
149
  );
@@ -3,5 +3,23 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.BORDER_REGEX = void 0;
7
- const BORDER_REGEX = exports.BORDER_REGEX = /^(?<width>(?: ?(?:[0-9]+)(?:px|pt|PC|in|cm|mm|em|rem|%|ex|ch|fr)?){0,4}) {0,1}(?<style>(?:(?: ?(?:none|hidden|dotted|dashed|solid|double|groove|ridge|inset|outset))+){0,4}) ?(?<color>(?: ?(?:(?:(?:#)(?:[a-f0-9]{3}|[a-f0-9]{6}))|(?:var\(--[^)]+\))|(?:(?:rgb|hsl|rgba)a?\(.*\))|(?:[A-Za-z]+))){0,4})$/;
6
+ exports.BORDER_REGEX = exports.BORDER_POSITION_MAP = void 0;
7
+ var _enums = require("../../enums/index.cjs");
8
+ const BORDER_REGEX = exports.BORDER_REGEX = /^(?<width>(?: ?(?:[0-9]+)(?:px|pt|PC|in|cm|mm|em|rem|%|ex|ch|fr)?){0,4}) {0,1}(?<style>(?:(?: ?(?:none|hidden|dotted|dashed|solid|double|groove|ridge|inset|outset))+){0,4}) ?(?<color>(?: ?(?:(?:(?:#)(?:[a-f0-9]{3}|[a-f0-9]{6}))|(?:var\(--[^)]+\))|(?:(?:rgb|hsl|rgba)a?\(.*\))|(?:[A-Za-z]+))){0,4})$/;
9
+ const BORDER_POSITION_MAP = exports.BORDER_POSITION_MAP = [{
10
+ side: _enums.BLOCK.TOP,
11
+ widthProp: "borderTop",
12
+ colorProp: "borderTopColor"
13
+ }, {
14
+ side: _enums.INLINE.RIGHT,
15
+ widthProp: "borderRight",
16
+ colorProp: "borderRightColor"
17
+ }, {
18
+ side: _enums.BLOCK.BOTTOM,
19
+ widthProp: "borderBottom",
20
+ colorProp: "borderBottomColor"
21
+ }, {
22
+ side: _enums.INLINE.LEFT,
23
+ widthProp: "borderLeft",
24
+ colorProp: "borderLeftColor"
25
+ }];
@@ -1,3 +1,4 @@
1
+ import { BLOCK, INLINE } from '../../enums';
1
2
  /**
2
3
  * Parse a free-form `border` value into width / style / color groups.
3
4
  *
@@ -17,3 +18,31 @@
17
18
  * fixes the design-token path.
18
19
  */
19
20
  export declare const BORDER_REGEX: RegExp;
21
+ /**
22
+ * Physical-side lookup driving the per-side border wiring (issue #215).
23
+ *
24
+ * `IBorderProps` names its discrete side props PHYSICALLY
25
+ * (`borderTop`/`borderRight`/`borderBottom`/`borderLeft`), unlike the
26
+ * global `border` shorthand's 4-value mode which distributes across
27
+ * LOGICAL axes (`block-start`/`inline-start`/…, see `formatBorderStylesVar`
28
+ * / issue #216). `useBorder` reads this map to emit matching PHYSICAL CSS
29
+ * declarations (`border-top-width`, …) — no logical/physical mismatch for
30
+ * the consumer to mentally translate.
31
+ */
32
+ export declare const BORDER_POSITION_MAP: readonly [{
33
+ readonly side: BLOCK.TOP;
34
+ readonly widthProp: "borderTop";
35
+ readonly colorProp: "borderTopColor";
36
+ }, {
37
+ readonly side: INLINE.RIGHT;
38
+ readonly widthProp: "borderRight";
39
+ readonly colorProp: "borderRightColor";
40
+ }, {
41
+ readonly side: BLOCK.BOTTOM;
42
+ readonly widthProp: "borderBottom";
43
+ readonly colorProp: "borderBottomColor";
44
+ }, {
45
+ readonly side: INLINE.LEFT;
46
+ readonly widthProp: "borderLeft";
47
+ readonly colorProp: "borderLeftColor";
48
+ }];
@@ -1 +1,8 @@
1
+ import { BLOCK, INLINE } from "../../enums/index.js";
1
2
  export const BORDER_REGEX = /^(?<width>(?: ?(?:[0-9]+)(?:px|pt|PC|in|cm|mm|em|rem|%|ex|ch|fr)?){0,4}) {0,1}(?<style>(?:(?: ?(?:none|hidden|dotted|dashed|solid|double|groove|ridge|inset|outset))+){0,4}) ?(?<color>(?: ?(?:(?:(?:#)(?:[a-f0-9]{3}|[a-f0-9]{6}))|(?:var\(--[^)]+\))|(?:(?:rgb|hsl|rgba)a?\(.*\))|(?:[A-Za-z]+))){0,4})$/;
3
+ export const BORDER_POSITION_MAP = [
4
+ { side: BLOCK.TOP, widthProp: "borderTop", colorProp: "borderTopColor" },
5
+ { side: INLINE.RIGHT, widthProp: "borderRight", colorProp: "borderRightColor" },
6
+ { side: BLOCK.BOTTOM, widthProp: "borderBottom", colorProp: "borderBottomColor" },
7
+ { side: INLINE.LEFT, widthProp: "borderLeft", colorProp: "borderLeftColor" }
8
+ ];
@@ -3,6 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.UTILITY_SHADOW_RUNGS = exports.ORIGAM_SHADOW_RUNGS = void 0;
6
+ exports.UTILITY_SHADOW_RUNGS = exports.ORIGAM_SHADOW_RUNGS = exports.CUSTOM_BOX_SHADOW_REGEX = void 0;
7
7
  const ORIGAM_SHADOW_RUNGS = exports.ORIGAM_SHADOW_RUNGS = /* @__PURE__ */new Set(["none", "xs", "sm", "md", "lg", "xl", "2xl", "3xl"]);
8
- const UTILITY_SHADOW_RUNGS = exports.UTILITY_SHADOW_RUNGS = /* @__PURE__ */new Set(["none", "xs", "sm", "md", "lg", "xl"]);
8
+ const UTILITY_SHADOW_RUNGS = exports.UTILITY_SHADOW_RUNGS = /* @__PURE__ */new Set(["none", "xs", "sm", "md", "lg", "xl"]);
9
+ const CUSTOM_BOX_SHADOW_REGEX = exports.CUSTOM_BOX_SHADOW_REGEX = /(?:var|calc|clamp|min|max|env|rgb|rgba|hsl|hsla|hwb|lab|lch|oklab|oklch|color-mix)\(|#[0-9a-f]{3,8}\b|[\d.]+(?:px|pt|pc|in|cm|mm|q|em|rem|ex|ch|cap|ic|lh|rlh|vw|vh|vi|vb|vmin|vmax|%)|\binset\b/i;
@@ -15,3 +15,23 @@ export declare const ORIGAM_SHADOW_RUNGS: ReadonlySet<string>;
15
15
  * to the inline-style path.
16
16
  */
17
17
  export declare const UTILITY_SHADOW_RUNGS: ReadonlySet<string>;
18
+ /**
19
+ * Detects a free-form custom `box-shadow` value that is neither an
20
+ * origam-native rung name (`ORIGAM_SHADOW_RUNGS`) nor a Material 0..24
21
+ * number — e.g. `'0 4px 12px rgba(0,0,0,.24)'`, a `var(--origam-shadow---card)`
22
+ * / `calc(...)` reference, multiple comma-separated shadow layers, or an
23
+ * `inset` shadow.
24
+ *
25
+ * Mirrors `CUSTOM_BORDER_RADIUS_REGEX` (`rounded.const.ts`): deliberately
26
+ * permissive, not a full box-shadow grammar validator. It only checks that
27
+ * the string carries at least one signal a real `box-shadow` value would
28
+ * have — a CSS function call (`var(`, `calc(`, `clamp(`, `rgb(`, `rgba(`,
29
+ * `hsl(`, `hsla(`, `hwb(`, `color-mix(`, …), a hex color, a CSS length with
30
+ * a unit, or the `inset` keyword. Anything that matches none of these is
31
+ * treated as not-a-shadow and falls through to the existing (silent-drop)
32
+ * behaviour — no regression for genuinely invalid input.
33
+ *
34
+ * Example matches: `'0 4px 12px rgba(0,0,0,.24)'`, `'var(--origam-shadow---card)'`,
35
+ * `'inset 0 0 0 2px #fff'`, `'0 1px 2px #000, 0 2px 8px #000'`.
36
+ */
37
+ export declare const CUSTOM_BOX_SHADOW_REGEX: RegExp;
@@ -16,3 +16,4 @@ export const UTILITY_SHADOW_RUNGS = /* @__PURE__ */ new Set([
16
16
  "lg",
17
17
  "xl"
18
18
  ]);
19
+ export const CUSTOM_BOX_SHADOW_REGEX = /(?:var|calc|clamp|min|max|env|rgb|rgba|hsl|hsla|hwb|lab|lch|oklab|oklch|color-mix)\(|#[0-9a-f]{3,8}\b|[\d.]+(?:px|pt|pc|in|cm|mm|q|em|rem|ex|ch|cap|ic|lh|rlh|vw|vh|vi|vb|vmin|vmax|%)|\binset\b/i;
@@ -1,4 +1,4 @@
1
- import type { IBgColorProps, IBorderProps, IColorProps, ICommonsComponentProps, IElevationProps, IMarginProps, IPaddingProps, IRoundedProps, ITagProps, ITypographyProps } from '../../interfaces';
1
+ import type { IAccentColorProps, IBgColorProps, IBorderProps, IColorProps, ICommonsComponentProps, IElevationProps, IMarginProps, IPaddingProps, IRoundedProps, ITagProps, ITypographyProps } from '../../interfaces';
2
2
  import type { TBlockquoteAlign, TBlockquoteLang, TBlockquoteVariant } from '../../types';
3
3
  /**
4
4
  * Props for `<OrigamBlockquote>` — typographic citation component.
@@ -12,21 +12,28 @@ import type { TBlockquoteAlign, TBlockquoteLang, TBlockquoteVariant } from '../.
12
12
  * - **`color`** drives the **citation text** itself (the body). Defaults
13
13
  * to `text-primary`. An intent resolves to its readable-on-light shade
14
14
  * (`fgSubtle`); a custom value is applied verbatim.
15
- * - **`bgColor`** drives the **accent**: the decorative bar / pull rules
16
- * (the "borders"), the big background quote glyph and the author label.
17
- * Defaults to `primary`. It does NOT paint a surface fill — the
18
- * blockquote stays transparent (see ROADMAP: future rename to
19
- * `accentColor`).
15
+ * - **`accentColor`** drives the **accent**: the decorative bar / pull
16
+ * rules (the "borders"), the big background quote glyph and the author
17
+ * label. Defaults to `primary`. It does NOT paint a surface fill — the
18
+ * blockquote stays transparent.
20
19
  *
21
20
  * The two axes are meant to contrast: a dark body (`color`) reads against
22
- * a coloured accent (`bgColor`).
21
+ * a coloured accent (`accentColor`).
22
+ *
23
+ * @deprecated `bgColor` — renamed to `accentColor` (see ROADMAP.md,
24
+ * "Renommer `bgColor` → `accentColor`"). `bgColor` keeps working as an
25
+ * alias (`accentColor ?? bgColor`, `accentColor` wins) and warns once via
26
+ * `warnDeprecatedProp`. Removal targeted for v3.0.0. Only Blockquote
27
+ * migrates in this pass — `bgColor` stays the canonical, non-deprecated
28
+ * name on surface-fill components (Btn, Card, Chip, Badge, Alert,
29
+ * Pagination, …), where "accent" would misrepresent a full fill.
23
30
  *
24
31
  * Standard cross-cutting surfaces (`rounded`, `elevation`, `border`,
25
32
  * `padding`, `margin`) are inherited from the Commons interfaces and
26
33
  * consumed via the matching composables. The component never imposes an
27
34
  * outer margin unless `margin` is passed.
28
35
  */
29
- export interface IBlockquoteProps extends ICommonsComponentProps, ITagProps, IColorProps, IBgColorProps, IRoundedProps, IElevationProps, IBorderProps, IPaddingProps, IMarginProps, ITypographyProps {
36
+ export interface IBlockquoteProps extends ICommonsComponentProps, ITagProps, IColorProps, IAccentColorProps, IBgColorProps, IRoundedProps, IElevationProps, IBorderProps, IPaddingProps, IMarginProps, ITypographyProps {
30
37
  /**
31
38
  * Visual variant. See `TBlockquoteVariant` for the per-variant
32
39
  * typographic contract.
@@ -1,4 +1,4 @@
1
- import { TDirectionBoth } from "../../types";
1
+ import { TColor, TDirectionBoth } from "../../types";
2
2
  export interface IBorderProps {
3
3
  border?: boolean | number | string | TDirectionBoth | Array<TDirectionBoth>;
4
4
  borderTop?: boolean | number | string;
@@ -9,4 +9,23 @@ export interface IBorderProps {
9
9
  borderInline?: boolean | number | string;
10
10
  borderColor?: string;
11
11
  borderStyle?: string;
12
+ /**
13
+ * Per-side color override (issue #215). Additive: absent by default,
14
+ * no behaviour change for existing consumers.
15
+ *
16
+ * Precedence (specific > global): `borderTopColor` wins over any
17
+ * color implied by `borderTop` (e.g. `borderTop="2px dashed red"`),
18
+ * which itself wins over the global `borderColor` / `border` shorthand
19
+ * for the top side. See `useBorder` JSDoc for the full precedence
20
+ * table.
21
+ *
22
+ * Accepts a {@link TColor} (semantic intent, raw CSS color, or falsy
23
+ * to opt out) — same input family as `color` / `bgColor`. Gradients
24
+ * are NOT supported on border colors (CSS `border-color` has no
25
+ * gradient form) and are silently ignored.
26
+ */
27
+ borderTopColor?: TColor;
28
+ borderRightColor?: TColor;
29
+ borderBottomColor?: TColor;
30
+ borderLeftColor?: TColor;
12
31
  }
@@ -47,3 +47,27 @@ export interface IColorProps {
47
47
  export interface IBgColorProps {
48
48
  bgColor?: TColor;
49
49
  }
50
+ /**
51
+ * Accent-only color contract.
52
+ *
53
+ * Combine with {@link IColorProps} on components that paint a
54
+ * **decorative accent** — a border bar, a background glyph, a pull-rule
55
+ * — rather than their own surface fill. `accentColor` is the canonical
56
+ * name for that axis (see ROADMAP.md — "Renommer `bgColor` →
57
+ * `accentColor`"). Do NOT reach for this on surface-fill components
58
+ * (Btn, Card, Chip, Badge, Alert, Pagination, …) — those keep
59
+ * {@link IBgColorProps}, whose `bgColor` paints a real
60
+ * `background-color`. Mixing the two meanings under the same prop name
61
+ * is exactly the confusion this interface exists to avoid.
62
+ *
63
+ * // Blockquote paints text (color) + a decorative accent (accentColor).
64
+ * interface IBlockquoteProps extends IColorProps, IAccentColorProps { … }
65
+ *
66
+ * `bgColor` remains a **deprecated alias** on components that migrate to
67
+ * `accentColor` — resolve it as `accentColor ?? bgColor` (accentColor
68
+ * wins) and warn once via `warnDeprecatedProp` from
69
+ * `src/utils/Commons/color.util.ts`. Removal targeted for v3.0.0.
70
+ */
71
+ export interface IAccentColorProps {
72
+ accentColor?: TColor;
73
+ }
@@ -1,3 +1,4 @@
1
+ import type { TElevation } from '../../types';
1
2
  export interface IElevationProps {
2
- elevation?: number | string;
3
+ elevation?: TElevation;
3
4
  }
@@ -0,0 +1 @@
1
+ "use strict";
@@ -0,0 +1,20 @@
1
+ /**
2
+ * `elevation` prop accepted by every component that consumes
3
+ * `useElevation` (`src/composables/Commons/elevation.composable.ts`).
4
+ *
5
+ * Three shapes are supported:
6
+ * - An origam-native shadow rung name — `'none' | 'xs' | 'sm' | 'md' |
7
+ * 'lg' | 'xl' | '2xl' | '3xl'` — resolves to `var(--origam-shadow---{rung})`.
8
+ * - A Material-style numeric elevation (`0..24`, as a `number` or a
9
+ * numeric `string`) — bucketised onto the origam shadow ladder.
10
+ * - A free-form custom `box-shadow` value (`var(...)`, `calc(...)`,
11
+ * a literal shadow list like `'0 4px 12px rgba(0,0,0,.24)'`, multiple
12
+ * comma-separated layers, `inset`, …) — emitted verbatim as
13
+ * `box-shadow: <value>`. Mirrors the `TRounded` custom-string escape
14
+ * hatch (`isCustomBorderRadius` in `rounded.util.ts`).
15
+ *
16
+ * The type stays a loose `number | string` union on purpose — the three
17
+ * shapes above are disambiguated at runtime by `useElevation`, not by the
18
+ * type system (same approach as `TRounded` for free-form radii).
19
+ */
20
+ export type TElevation = number | string;
File without changes
@@ -564,6 +564,17 @@ Object.keys(_dimension).forEach(function (key) {
564
564
  }
565
565
  });
566
566
  });
567
+ var _elevation = require("./Commons/elevation.type.cjs");
568
+ Object.keys(_elevation).forEach(function (key) {
569
+ if (key === "default" || key === "__esModule") return;
570
+ if (key in exports && exports[key] === _elevation[key]) return;
571
+ Object.defineProperty(exports, key, {
572
+ enumerable: true,
573
+ get: function () {
574
+ return _elevation[key];
575
+ }
576
+ });
577
+ });
567
578
  var _variant = require("./Commons/variant.type.cjs");
568
579
  Object.keys(_variant).forEach(function (key) {
569
580
  if (key === "default" || key === "__esModule") return;
@@ -49,6 +49,7 @@ export * from './Commons/letter-spacing.type';
49
49
  export * from './Commons/line-height.type';
50
50
  export * from './Commons/rounded.type';
51
51
  export * from './Commons/dimension.type';
52
+ export * from './Commons/elevation.type';
52
53
  export * from './Commons/variant.type';
53
54
  export * from './Commons/direction.type';
54
55
  export * from './Commons/display.type';
@@ -49,6 +49,7 @@ export * from "./Commons/letter-spacing.type.js";
49
49
  export * from "./Commons/line-height.type.js";
50
50
  export * from "./Commons/rounded.type.js";
51
51
  export * from "./Commons/dimension.type.js";
52
+ export * from "./Commons/elevation.type.js";
52
53
  export * from "./Commons/variant.type.js";
53
54
  export * from "./Commons/direction.type.js";
54
55
  export * from "./Commons/display.type.js";