lupine.components 1.1.59 → 1.1.61

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lupine.components",
3
- "version": "1.1.59",
3
+ "version": "1.1.61",
4
4
  "license": "MIT",
5
5
  "author": "uuware.com",
6
6
  "homepage": "https://github.com/uuware/lupine.js",
@@ -322,7 +322,7 @@ export const slidePageDemo: DemoStory<SlidePageProps> = {
322
322
  style={{
323
323
  padding: '12px 16px',
324
324
  borderRadius: '8px',
325
- background: 'var(--bg-container, #f2f2f7)',
325
+ background: 'var(--secondary-bg-color, #f2f2f7)',
326
326
  fontSize: '13px',
327
327
  color: 'var(--text-secondary, #64748b)',
328
328
  lineHeight: '1.5',
@@ -28,7 +28,7 @@ export const DemoContainer = (props: DemoContainerProps) => {
28
28
  minHeight: '50px',
29
29
  maxHeight: '40%',
30
30
  overflowY: 'auto',
31
- borderTop: '1px solid var(--border-color, #ccc)',
31
+ borderTop: '1px solid var(--secondary-border-color, #ccc)',
32
32
  padding: 'var(--space-m, 8px)',
33
33
  },
34
34
  };
@@ -16,7 +16,7 @@ import { MediaQueryMaxWidth, VNode, stopPropagation } from 'lupine.components';
16
16
  import { SliderHelper, SliderHelperCloseProps } from './slider-helper';
17
17
 
18
18
  export type SliderFrameHookProps = {
19
- load?: (children: VNode<any>) => void;
19
+ load?: (children: VNode<any>, addBottomSafearea?: boolean) => void;
20
20
  close?: (event: Event) => void;
21
21
  isOpened?: () => boolean;
22
22
  };
@@ -34,13 +34,13 @@ export const SliderFrame = (props: SliderFrameProps) => {
34
34
  let opened = false;
35
35
 
36
36
  if (props.hook) {
37
- props.hook.load = (children) => {
37
+ props.hook.load = (children, addBottomSafearea) => {
38
38
  opened = true;
39
39
  SliderHelper.show({
40
40
  direction: props.direction || 'right',
41
41
  children,
42
42
  maxWidth: props.maxWidth,
43
- addBottomSafearea: props.addBottomSafearea ?? false,
43
+ addBottomSafearea: typeof addBottomSafearea === 'boolean' ? addBottomSafearea : (props.addBottomSafearea ?? false),
44
44
  closeEvent: () => {
45
45
  opened = false;
46
46
  closeSlider = undefined;
package/src/lib/index.ts CHANGED
@@ -18,6 +18,7 @@ export * from './dynamical-load';
18
18
  export * from './find-parent-tag';
19
19
  export * from './format-bytes';
20
20
  export * from './lite-dom';
21
+ export * from './local-storage-wrapper'
21
22
  export * from './message-hub';
22
23
  export * from './observable';
23
24
  export * from './path-utils';
@@ -0,0 +1,47 @@
1
+ export class LocalStorageWrapper {
2
+ private prefix: string;
3
+
4
+ /**
5
+ * Creates an instance of LocStorage.
6
+ * @param prefix - The prefix applied to all storage keys.
7
+ */
8
+ constructor(prefix: string) {
9
+ this.prefix = prefix;
10
+ }
11
+
12
+ set(key: string, value: string | null) {
13
+ if (typeof window === 'undefined') return;
14
+ if (value === null) {
15
+ window.localStorage.removeItem(this.makeKey(key));
16
+ return;
17
+ }
18
+ window.localStorage.setItem(this.makeKey(key), value);
19
+ }
20
+ get(key: string): string | null {
21
+ if (typeof window === 'undefined') return null;
22
+ return window.localStorage.getItem(this.makeKey(key));
23
+ }
24
+ setJson(key: string, value: object | null) {
25
+ if (typeof window === 'undefined') return;
26
+ if (value === null) {
27
+ window.localStorage.removeItem(this.makeKey(key));
28
+ return;
29
+ }
30
+ window.localStorage.setItem(this.makeKey(key), JSON.stringify(value));
31
+ }
32
+ getJson(key: string): object | null {
33
+ if (typeof window === 'undefined') return null;
34
+ const val = window.localStorage.getItem(this.makeKey(key));
35
+ try {
36
+ if (!val) return null;
37
+ return JSON.parse(val);
38
+ } catch (error) {
39
+ console.error(`[LocalStorage Error] Failed to get key "${key}":`, error);
40
+ return null;
41
+ }
42
+ }
43
+
44
+ private makeKey(key: string): string {
45
+ return `${this.prefix}${key}`;
46
+ }
47
+ }
@@ -0,0 +1,103 @@
1
+ import { blendColor } from "lupine.web";
2
+
3
+ export interface ComputedThemeVars {
4
+ '--primary-color': string;
5
+ '--primary-bg-color': string;
6
+ '--primary-border-color': string;
7
+ '--primary-border': string;
8
+ '--primary-color-disabled': string;
9
+ '--primary-disabled-opacity': string;
10
+ '--secondary-color': string;
11
+ '--secondary-bg-color': string;
12
+ '--secondary-border-color': string;
13
+ '--secondary-border': string;
14
+ '--activatable-color-normal': string;
15
+ '--activatable-bg-color-normal': string;
16
+ '--activatable-color-hover': string;
17
+ '--activatable-bg-color-hover': string;
18
+ '--activatable-color-selected': string;
19
+ '--activatable-bg-color-selected': string;
20
+ }
21
+
22
+ /**
23
+ * Computes a full set of global theme CSS variables from the theme mode,
24
+ * primary background color, and primary text color.
25
+ *
26
+ * Design Specifications:
27
+ * - `--secondary-color` (Secondary / Muted Text):
28
+ * - Dark mode: blendColor(primaryText, primaryBg, 0.38) (~62% text + 38% bg)
29
+ * - Light mode: blendColor(primaryText, primaryBg, 0.42) (~58% text + 42% bg)
30
+ * - Ensures soft readability while strictly meeting WCAG AA contrast standards (>= 4.5:1).
31
+ * - `--secondary-bg-color` (Surface / Card / Modal Background):
32
+ * - Dark mode: blendColor(primaryBg, '#FFFFFF', 0.10) (elevated by +10% lightness)
33
+ * - Light mode: blendColor(primaryBg, '#FFFFFF', 0.55) (elevated towards white by +55%)
34
+ * - `--primary-border-color` & `--secondary-border-color`:
35
+ * - Balanced contrast border tints for cards, buttons, and dividers.
36
+ * - `--activatable-...`:
37
+ * - Normal, hover, and selected states for buttons, tabs, pills, and menus.
38
+ */
39
+ export function computeThemeVars(mode: 'light' | 'dark', primaryBg: string, primaryText: string): ComputedThemeVars {
40
+ const isDark = mode === 'dark';
41
+
42
+ // 1. Secondary Text
43
+ const secondaryColor = isDark
44
+ ? blendColor(primaryText, primaryBg, 0.38)
45
+ : blendColor(primaryText, primaryBg, 0.42);
46
+
47
+ // 2. Card / Surface Elevation Background
48
+ const secondaryBg = isDark
49
+ ? blendColor(primaryBg, '#FFFFFF', 0.10)
50
+ : blendColor(primaryBg, '#FFFFFF', 0.55);
51
+
52
+ // 3. Borders & Dividers
53
+ const primaryBorderColor = isDark
54
+ ? blendColor(primaryBg, primaryText, 0.35)
55
+ : blendColor(primaryBg, primaryText, 0.25);
56
+
57
+ const secondaryBorderColor = isDark
58
+ ? blendColor(primaryBg, primaryText, 0.18)
59
+ : blendColor(primaryBg, primaryText, 0.12);
60
+
61
+ // 4. Disabled Text
62
+ const primaryColorDisabled = isDark
63
+ ? blendColor(primaryText, primaryBg, 0.60)
64
+ : blendColor(primaryText, primaryBg, 0.65);
65
+
66
+ // 5. Activatable Hover State
67
+ const activatableBgHover = isDark
68
+ ? blendColor(primaryBg, '#FFFFFF', 0.16)
69
+ : blendColor(primaryBg, primaryText, 0.08);
70
+
71
+ const activatableColorHover = isDark ? '#FFFFFF' : primaryText;
72
+
73
+ // 6. Activatable Selected State
74
+ const activatableBgSelected = isDark
75
+ ? blendColor(primaryBg, '#FFFFFF', 0.22)
76
+ : blendColor(primaryBg, primaryText, 0.14);
77
+
78
+ const activatableColorSelected = isDark ? '#FFFFFF' : primaryText;
79
+
80
+ return {
81
+ // Primary Group
82
+ '--primary-color': primaryText,
83
+ '--primary-bg-color': primaryBg,
84
+ '--primary-border-color': primaryBorderColor,
85
+ '--primary-border': `1px solid ${primaryBorderColor}`,
86
+ '--primary-color-disabled': primaryColorDisabled,
87
+ '--primary-disabled-opacity': isDark ? '0.6' : '0.45',
88
+
89
+ // Secondary Group
90
+ '--secondary-color': secondaryColor,
91
+ '--secondary-bg-color': secondaryBg,
92
+ '--secondary-border-color': secondaryBorderColor,
93
+ '--secondary-border': `1px solid ${secondaryBorderColor}`,
94
+
95
+ // Activatable Group (Buttons, Pills, Tabs, Menus)
96
+ '--activatable-color-normal': primaryText,
97
+ '--activatable-bg-color-normal': secondaryBg,
98
+ '--activatable-color-hover': activatableColorHover,
99
+ '--activatable-bg-color-hover': activatableBgHover,
100
+ '--activatable-color-selected': activatableColorSelected,
101
+ '--activatable-bg-color-selected': activatableBgSelected,
102
+ };
103
+ }
@@ -1,5 +1,6 @@
1
- export * from './media-query';
2
- export * from './shared-themes';
1
+ export * from './base-themes';
2
+ export * from './compute-theme-vars';
3
3
  export * from './dark-themes';
4
4
  export * from './light-themes';
5
- export * from './base-themes';
5
+ export * from './media-query';
6
+ export * from './shared-themes';