@santi020k/lumen-react 4.0.0 → 4.3.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.
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { createElement } from 'react';
3
- import { composeClassName } from '@santi020k/lumen-core';
3
+ import { composeClassName, normalizeLumenProgress, resolveLumenLoadingSemantics, resolveLumenSkeletonAnimation, resolveLumenSkeletonShape, resolveLumenSkeletonSize } from '@santi020k/lumen-core';
4
4
  const Primitive = ({ as, className, uiClassName, ...props }) => {
5
5
  const tag = as ?? 'div';
6
6
  const safeClassName = typeof className === 'string' ? className : undefined;
@@ -42,16 +42,24 @@ export const Grid = ({ as = 'div', className, columns = 'auto', gap = 'group', m
42
42
  export const Input = ({ className, ref, type = 'text', visualSize = 'default', ...props }) => (_jsx("input", { className: composeClassName('ui-input', visualSize === 'sm' && 'ui-input--sm', visualSize === 'lg' && 'ui-input--lg', className), ref: ref, type: type, ...props }));
43
43
  export const Label = ({ className, ...props }) => (_jsx("label", { className: composeClassName('ui-label', className), ...props }));
44
44
  export const Progress = ({ className, max = 100, value = 0, ...props }) => {
45
- const safeMax = max > 0 ? max : 100;
46
- const safeValue = Math.min(safeMax, Math.max(0, value));
47
- const percentage = (safeValue / safeMax) * 100;
45
+ const { max: safeMax, percentage, value: safeValue } = normalizeLumenProgress(max, value);
48
46
  return (_jsx("div", { "aria-valuemax": safeMax, "aria-valuemin": 0, "aria-valuenow": safeValue, className: composeClassName('ui-progress', className), role: "progressbar", ...props, children: _jsx("span", { className: "ui-progress__bar", "data-slot": "progress-indicator", style: { width: `${percentage}%` } }) }));
49
47
  };
50
48
  export const Separator = ({ className, orientation = 'horizontal', ...props }) => (_jsx("hr", { "aria-orientation": orientation, className: composeClassName('ui-separator', `ui-separator--${orientation}`, className), "data-orientation": orientation, ...props }));
51
- export const Skeleton = ({ className, ...props }) => (_jsx("div", { className: composeClassName('ui-skeleton', className), ...props }));
49
+ export const Skeleton = ({ animation, 'aria-hidden': ariaHidden, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledby, className, height, role, shape, style, width, ...props }) => {
50
+ const semantics = resolveLumenLoadingSemantics({ ariaHidden, ariaLabel, ariaLabelledby, role });
51
+ const resolvedShape = resolveLumenSkeletonShape(shape);
52
+ const resolvedAnimation = resolveLumenSkeletonAnimation(animation);
53
+ const skeletonStyle = {
54
+ '--ui-skeleton-height': resolveLumenSkeletonSize(height),
55
+ '--ui-skeleton-width': resolveLumenSkeletonSize(width),
56
+ ...style
57
+ };
58
+ return (_jsx("div", { "aria-hidden": ariaHidden ?? (semantics.ariaHidden ? true : undefined), "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, className: composeClassName('ui-skeleton', resolvedShape !== 'rectangle' && `ui-skeleton--${resolvedShape}`, resolvedAnimation === 'pulse' && 'ui-skeleton--pulse', resolvedAnimation === 'none' && 'ui-skeleton--static', className), role: role ?? semantics.role, style: skeletonStyle, ...props }));
59
+ };
52
60
  export const Spinner = ({ 'aria-hidden': ariaHidden, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledby, className, role, ...props }) => {
53
- const isAccessible = Boolean(ariaLabel || ariaLabelledby);
54
- return (_jsx("span", { "aria-hidden": ariaHidden ?? (isAccessible ? undefined : true), "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, className: composeClassName('ui-spinner', className), role: role ?? (isAccessible ? 'status' : undefined), ...props }));
61
+ const semantics = resolveLumenLoadingSemantics({ ariaHidden, ariaLabel, ariaLabelledby, role });
62
+ return (_jsx("span", { "aria-hidden": ariaHidden ?? (semantics.ariaHidden ? true : undefined), "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, className: composeClassName('ui-spinner', className), role: role ?? semantics.role, ...props }));
55
63
  };
56
64
  export const Stack = ({ align = 'stretch', as = 'div', className, direction = 'vertical', gap = 'group', justify = 'start', wrap = false, ...props }) => createElement(as, {
57
65
  className: composeClassName('ui-stack', `ui-stack--${direction}`, `ui-stack--gap-${gap}`, `ui-stack--align-${align}`, `ui-stack--justify-${justify}`, wrap && 'ui-stack--wrap', className),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@santi020k/lumen-react",
3
- "version": "4.0.0",
3
+ "version": "4.3.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -10,7 +10,8 @@
10
10
  "./layers.css",
11
11
  "./styles.css",
12
12
  "./styles/critical.css",
13
- "./styles/data-table-view.css"
13
+ "./styles/data-table-view.css",
14
+ "./tailwind.css"
14
15
  ],
15
16
  "main": "./dist/index.js",
16
17
  "module": "./dist/index.js",
@@ -108,7 +109,8 @@
108
109
  "./components/media-selection": {
109
110
  "types": "./dist/media-selection.d.ts",
110
111
  "import": "./dist/media-selection.js"
111
- }
112
+ },
113
+ "./tailwind.css": "./tailwind.css"
112
114
  },
113
115
  "files": [
114
116
  "bin",
@@ -117,15 +119,16 @@
117
119
  "styles.css",
118
120
  "styles",
119
121
  "README.md",
120
- "LICENSE"
122
+ "LICENSE",
123
+ "tailwind.css"
121
124
  ],
122
125
  "bin": {
123
126
  "lumen": "./bin/lumen.mjs"
124
127
  },
125
128
  "dependencies": {
126
- "@santi020k/lumen": "^4.0.0",
127
- "@santi020k/lumen-core": "^4.0.0",
128
- "@tanstack/react-table": "9.2.4",
129
+ "@santi020k/lumen": "^4.3.0",
130
+ "@santi020k/lumen-core": "^4.3.0",
131
+ "@tanstack/react-table": "9.3.1",
129
132
  "uqr": "^0.1.3"
130
133
  },
131
134
  "devDependencies": {
@@ -134,7 +137,7 @@
134
137
  "@vitest/coverage-v8": "^5.0.3",
135
138
  "esbuild": "^0.28.2",
136
139
  "jsdom": "^30.1.1",
137
- "motion": "14.0.0",
140
+ "motion": "14.6.0",
138
141
  "react": "19.2.3",
139
142
  "react-dom": "19.2.3",
140
143
  "typescript": "~6.0.3",
@@ -172,6 +172,17 @@
172
172
  }
173
173
  }
174
174
 
175
+ @keyframes ui-skeleton-pulse {
176
+ 0%,
177
+ 100% {
178
+ opacity: 1;
179
+ }
180
+
181
+ 50% {
182
+ opacity: 0.55;
183
+ }
184
+ }
185
+
175
186
  @keyframes ui-spin {
176
187
  to {
177
188
  transform: rotate(360deg);
@@ -790,15 +801,21 @@
790
801
  background-image:
791
802
  linear-gradient(45deg, transparent 50%, hsl(var(--ink-muted)) 50%),
792
803
  linear-gradient(135deg, hsl(var(--ink-muted)) 50%, transparent 50%);
793
- background-position:
794
- calc(100% - 1rem) 50%,
795
- calc(100% - 0.72rem) 50%;
804
+ background-position: var(--_ui-select-chevron, calc(100% - 1rem) 50%, calc(100% - 0.72rem) 50%);
796
805
  background-size:
797
806
  0.32rem 0.32rem,
798
807
  0.32rem 0.32rem;
799
808
  background-repeat: no-repeat;
800
809
  }
801
810
 
811
+ [dir="rtl"] {
812
+ --_ui-select-chevron: 0.72rem 50%, 1rem 50%;
813
+ }
814
+
815
+ [dir="ltr"] {
816
+ --_ui-select-chevron: calc(100% - 1rem) 50%, calc(100% - 0.72rem) 50%;
817
+ }
818
+
802
819
  .ui-label {
803
820
  color: hsl(var(--ink));
804
821
  font-size: 0.875rem;
@@ -820,6 +837,10 @@
820
837
  width: min(100%, 34rem);
821
838
  }
822
839
 
840
+ lumen-date-picker.ui-date-picker-field {
841
+ display: block;
842
+ }
843
+
823
844
  .ui-combobox > .ui-input {
824
845
  width: 100%;
825
846
  }
@@ -1007,7 +1028,9 @@
1007
1028
  }
1008
1029
 
1009
1030
  .ui-skeleton {
1010
- min-height: 1rem;
1031
+ /* A default height, not a minimum, lets explicit styles and classes size placeholders below 1rem. */
1032
+ width: var(--ui-skeleton-width, auto);
1033
+ height: var(--ui-skeleton-height, 1rem);
1011
1034
  border-radius: var(--ui-radius-sm);
1012
1035
  background: linear-gradient(
1013
1036
  90deg,
@@ -1019,6 +1042,42 @@
1019
1042
  animation: ui-shimmer 2.2s linear infinite;
1020
1043
  }
1021
1044
 
1045
+ .ui-skeleton:where(:not(:empty)) {
1046
+ height: var(--ui-skeleton-height, auto);
1047
+ min-height: 1rem;
1048
+ }
1049
+
1050
+ lumen-skeleton.ui-skeleton,
1051
+ lumen-progress.ui-progress {
1052
+ display: block;
1053
+ }
1054
+
1055
+ .ui-skeleton--text {
1056
+ height: var(--ui-skeleton-height, 0.75rem);
1057
+ }
1058
+
1059
+ .ui-skeleton--circle {
1060
+ flex: 0 0 auto;
1061
+ width: var(--ui-skeleton-width, var(--ui-skeleton-height, 2.5rem));
1062
+ height: var(--ui-skeleton-height, var(--ui-skeleton-width, 2.5rem));
1063
+ border-radius: 50%;
1064
+ }
1065
+
1066
+ .ui-skeleton--pulse {
1067
+ background: hsl(var(--surface-strong));
1068
+ animation: ui-skeleton-pulse 1.6s ease-in-out infinite;
1069
+ }
1070
+
1071
+ .ui-skeleton--static {
1072
+ animation: none;
1073
+ }
1074
+
1075
+ @media (prefers-reduced-motion: reduce) {
1076
+ .ui-skeleton {
1077
+ animation: none;
1078
+ }
1079
+ }
1080
+
1022
1081
  .ui-spinner {
1023
1082
  box-sizing: border-box;
1024
1083
  display: inline-block;
@@ -1586,7 +1645,9 @@ lumen-dialog.ui-dialog:not([hidden]):has(> [data-slot="dialog-body"]) {
1586
1645
 
1587
1646
  .ui-input-otp__native[data-ui-enhanced="true"] {
1588
1647
  position: absolute;
1589
- width: 1px;
1648
+ inset-block-start: 0;
1649
+ inset-inline-start: 0;
1650
+ width: 100%;
1590
1651
  height: 1px;
1591
1652
  overflow: hidden;
1592
1653
  clip-path: inset(50%);
package/tailwind.css ADDED
@@ -0,0 +1 @@
1
+ @import "@santi020k/lumen/tailwind.css";