lucentia-ui 0.2.12 → 0.2.13

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 +1 @@
1
- export declare function ThemeSwitch(): import("react/jsx-runtime").JSX.Element;
1
+ export declare function ThemeSwitch(): import("react/jsx-runtime").JSX.Element | null;
@@ -1,9 +1,21 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useState } from "react";
3
4
  import { useTheme } from "../../ThemeProvider";
4
5
  import styles from "./ThemeSwitch.module.css";
5
6
  export function ThemeSwitch() {
6
7
  const { theme, toggleTheme } = useTheme();
7
8
  const isDark = theme === "dark";
8
- return (_jsxs("label", { className: styles.switch, children: [_jsx("input", { type: "checkbox", checked: isDark, onChange: toggleTheme, "aria-label": "Toggle theme" }), _jsx("span", { className: styles.slider, children: _jsxs("span", { className: styles.circle, children: [Array.from({ length: 8 }).map((_, i) => (_jsx("span", { className: `${styles.shine} ${styles[`shine${i + 1}`]}` }, i))), _jsx("span", { className: styles.moon })] }) })] }));
9
+ const [mounted, setMounted] = useState(false);
10
+ const [animate, setAnimate] = useState(false);
11
+ useEffect(() => {
12
+ setMounted(true);
13
+ // 次フレームで transition を有効化
14
+ requestAnimationFrame(() => {
15
+ setAnimate(true);
16
+ });
17
+ }, []);
18
+ if (!mounted)
19
+ return null;
20
+ return (_jsxs("label", { className: styles.switch, "data-mounted": true, "data-animate": animate ? "" : undefined, children: [_jsx("input", { type: "checkbox", checked: isDark, onChange: toggleTheme, "aria-label": "Toggle theme" }), _jsx("span", { className: styles.slider, children: _jsxs("span", { className: styles.circle, children: [Array.from({ length: 8 }).map((_, i) => (_jsx("span", { className: `${styles.shine} ${styles[`shine${i + 1}`]}` }, i))), _jsx("span", { className: styles.moon })] }) })] }));
9
21
  }
@@ -1,112 +1,129 @@
1
- /* The switch - the box around the slider */
1
+ /* =========================
2
+ ThemeSwitch
3
+ ========================= */
4
+
5
+ /* ---------- 初期描画制御 ---------- */
6
+ /* data-animate が付くまで transition を完全無効化 */
7
+ .switch:not([data-animate]) .slider,
8
+ .switch:not([data-animate]) .circle,
9
+ .switch:not([data-animate]) .moon,
10
+ .switch:not([data-animate]) .shine {
11
+ transition: none;
12
+ }
13
+
14
+ /* ---------- Switch root ---------- */
2
15
  .switch {
3
- font-size: 17px;
4
- position: relative;
5
- display: inline-block;
6
- width: 4.8em;
7
- height: 2.4em;
16
+ font-size: 17px;
17
+ position: relative;
18
+ display: inline-block;
19
+ width: 4.8em;
20
+ height: 2.4em;
8
21
  }
9
22
 
10
- /* Hide default HTML checkbox */
23
+ /* ---------- Native checkbox ---------- */
11
24
  .switch input {
12
- opacity: 0;
13
- width: 0;
14
- height: 0;
25
+ opacity: 0;
26
+ width: 0;
27
+ height: 0;
15
28
  }
16
29
 
17
- /* The slider */
30
+ /* ---------- Slider ---------- */
18
31
  .slider {
19
- position: absolute;
20
- cursor: pointer;
21
- inset: 0;
22
- background-color: var(--color-surface-container);
23
- box-shadow: var(--shadow-md-in);
24
- transition: 0.4s;
25
- border-radius: 30px;
26
- overflow: hidden;
32
+ position: absolute;
33
+ inset: 0;
34
+ cursor: pointer;
35
+ background-color: var(--color-surface-container);
36
+ box-shadow: var(--shadow-md-in);
37
+ border-radius: 30px;
38
+ overflow: hidden;
27
39
  }
28
40
 
41
+ /* ---------- Circle ---------- */
29
42
  .circle {
30
- position: absolute;
31
- height: 1.2em;
32
- width: 1.2em;
33
- border-radius: 20px;
34
- left: 1em;
35
- bottom: 0.7em;
36
- background-color: var(--color-primary);
37
- transition: 0.4s;
43
+ position: absolute;
44
+ left: 0.9em;
45
+ bottom: 0.7em;
46
+ width: 1.05em;
47
+ height: 1.05em;
48
+ border-radius: 20px;
49
+ background-color: var(--color-primary);
50
+
51
+ transition: transform 0.4s;
38
52
  }
39
53
 
40
- /* checked state */
41
- .switch input:checked+.slider .circle {
42
- transform: translateX(1.5em);
54
+ /* ---------- Checked state ---------- */
55
+ .switch input:checked + .slider .circle {
56
+ transform: translateX(1.5em);
43
57
  }
44
58
 
45
- .switch input:checked+.slider .circle .shine {
46
- transform: translate(0%, 0%);
59
+ .switch input:checked + .slider .circle .shine {
60
+ transform: translate(0%, 0%);
47
61
  }
48
62
 
49
- .switch input:checked+.slider .circle .moon {
50
- left: -10%;
51
- opacity: 1;
52
- transform: translateY(-60%);
63
+ .switch input:checked + .slider .circle .moon {
64
+ left: -10%;
65
+ opacity: 1;
66
+ transform: translateY(-60%);
53
67
  }
54
68
 
55
- /* Moon */
69
+ /* ---------- Moon ---------- */
56
70
  .moon {
57
- position: absolute;
58
- left: -100%;
59
- top: 50%;
60
- opacity: 0;
61
- background-color: var(--color-surface-container);
62
- width: 1.25rem;
63
- height: 1.25rem;
64
- border-radius: 99999px;
65
- transform: translateY(-50%);
66
- transition: all 0.4s;
67
- }
68
-
69
- /* Shine */
71
+ position: absolute;
72
+ left: -100%;
73
+ top: 50%;
74
+ width: 1.25rem;
75
+ height: 1.25rem;
76
+ border-radius: 99999px;
77
+ background-color: var(--color-surface-container);
78
+
79
+ opacity: 0;
80
+ transform: translateY(-50%);
81
+
82
+ transition: transform 0.4s;
83
+ }
84
+
85
+ /* ---------- Shine ---------- */
70
86
  .shine {
71
- position: absolute;
72
- top: 50%;
73
- left: 50%;
74
- width: 0.25rem;
75
- height: 0.25rem;
76
- background-color: var(--color-primary);
77
- border-radius: 1rem;
78
- transition: all 0.4s;
87
+ position: absolute;
88
+ top: 50%;
89
+ left: 50%;
90
+ width: 0.25rem;
91
+ height: 0.25rem;
92
+ border-radius: 1rem;
93
+ background-color: var(--color-primary);
94
+
95
+ transition: transform 0.4s;
79
96
  }
80
97
 
81
- /* Individual shine positions */
98
+ /* ---------- Shine positions ---------- */
82
99
  .shine1 {
83
- transform: translate(-50%, -375%);
100
+ transform: translate(-50%, -375%);
84
101
  }
85
102
 
86
103
  .shine2 {
87
- transform: translate(175%, -275%);
104
+ transform: translate(175%, -275%);
88
105
  }
89
106
 
90
107
  .shine3 {
91
- transform: translate(275%, -50%);
108
+ transform: translate(275%, -50%);
92
109
  }
93
110
 
94
111
  .shine4 {
95
- transform: translate(175%, 175%);
112
+ transform: translate(175%, 175%);
96
113
  }
97
114
 
98
115
  .shine5 {
99
- transform: translate(-50%, 275%);
116
+ transform: translate(-50%, 275%);
100
117
  }
101
118
 
102
119
  .shine6 {
103
- transform: translate(-275%, 175%);
120
+ transform: translate(-275%, 175%);
104
121
  }
105
122
 
106
123
  .shine7 {
107
- transform: translate(-375%, -50%);
124
+ transform: translate(-375%, -50%);
108
125
  }
109
126
 
110
127
  .shine8 {
111
- transform: translate(-275%, -275%);
112
- }
128
+ transform: translate(-275%, -275%);
129
+ }
@@ -1,165 +0,0 @@
1
- .theme {
2
- min-height: 100%;
3
- font-family:
4
- var(--font),
5
- system-ui,
6
- -apple-system,
7
- sans-serif;
8
- background: var(--color-background);
9
-
10
- /* font */
11
- --font: "Noto Sans JP", sans-serif;
12
-
13
- --font-size-12: 12px;
14
- --font-size-14: 14px;
15
- --font-size-16: 16px;
16
- --font-size-18: 18px;
17
- --font-size-20: 20px;
18
- --font-size-24: 24px;
19
- --font-size-28: 28px;
20
- --font-size-40: 40px;
21
- --font-size-48: 48px;
22
-
23
- --line-tight: 1.2;
24
- --line-snug: 1.35;
25
- --line-normal: 1.6;
26
-
27
- --font-weight-regular: 400;
28
- --font-weight-medium: 500;
29
- --font-weight-bold: 600;
30
- --font-weight-black: 700;
31
-
32
- /* ===== Radius ===== */
33
- --radius-xs: 4px;
34
- --radius-sm: 8px;
35
- --radius-md: 16px;
36
- --radius-max: 999px;
37
-
38
- /* ===== Space ===== */
39
- --space-xs: 4px;
40
- --space-sm: 8px;
41
- --space-md: 12px;
42
- --space-lg: 16px;
43
- --space-xl: 24px;
44
- --space-2xl: 32px;
45
- --space-3xl: 48px;
46
- --space-4xl: 64px;
47
- --space-5xl: 96px;
48
- --gap-sm: 16px;
49
- --gap-md: 32px;
50
- --gap-lg: 64px;
51
-
52
- /* ===== Layout ===== */
53
- --container: 1120px;
54
- }
55
-
56
- .light {
57
- /* ===== Color ===== */
58
- --color-primary: #00a1a1;
59
- --color-on-primary: #ffffff;
60
- --color-primary-container: #9cf1f0;
61
- --color-on-primary-container: #004f4f;
62
-
63
- --color-secondary: #7b9695;
64
- --color-on-secondary: #ffffff;
65
- --color-secondary-container: #cce8e7;
66
- --color-on-secondary-container: #324b4b;
67
-
68
- --color-error: #ff5449;
69
- --color-on-error: #ffffff;
70
- --color-error-container: #ffdad6;
71
- --color-on-error-container: #93000a;
72
-
73
- --color-background: #f4fbfa;
74
- --color-on-background: #161d1d;
75
-
76
- --color-surface: #f4fbfabf;
77
- --color-on-surface: #161d1d;
78
- --color-on-surface-variant: #161d1d80;
79
- --color-surface-container: #e9efeebf;
80
-
81
- --color-border: #bbcccc;
82
- --color-scrim: rgba(129, 129, 129, 0.25);
83
-
84
- --color-shadow-l: rgba(255, 255, 255, 1);
85
- --color-shadow-d: rgba(0, 0, 0, 0.2);
86
-
87
- /* ===== Effect ===== */
88
- --blur: blur(8px);
89
-
90
- --shadow-sm:
91
- -2px -2px 2px 1px var(--color-shadow-l),
92
- 2px 2px 2px 1px var(--color-shadow-d);
93
-
94
- --shadow-sm-in:
95
- inset -2px -2px 2px var(--color-shadow-l),
96
- inset 2px 2px 2px var(--color-shadow-d);
97
-
98
- --shadow-md:
99
- -2px -2px 4px 2px var(--color-shadow-l),
100
- 2px 2px 4px 2px var(--color-shadow-d);
101
-
102
- --shadow-md-in:
103
- inset -4px -4px 4px var(--color-shadow-l),
104
- inset 4px 4px 4px var(--color-shadow-d);
105
-
106
- --shadow-lg:
107
- -4px -4px 16px 8px var(--color-shadow-l),
108
- 4px 4px 16px 8px var(--color-shadow-d);
109
-
110
- --shadow-surface-lg:
111
- 0px 4px 16px 8px var(--color-shadow-d);
112
- }
113
-
114
- .dark {
115
- --color-primary: #80d5d4;
116
- --color-on-primary: #003737;
117
- --color-primary-container: #004f4f;
118
- --color-on-primary-container: #9cf1f0;
119
-
120
- --color-secondary: #b0cccb;
121
- --color-on-secondary: #1b3534;
122
- --color-secondary-container: #324b4b;
123
- --color-on-secondary-container: #cce8e7;
124
-
125
- --color-error: #ffb4ab;
126
- --color-on-error: #690005;
127
- --color-error-container: #93000a;
128
- --color-on-error-container: #ffdad6;
129
-
130
- --color-background: #2b3a38;
131
- --color-on-background: #dde4e3;
132
-
133
- --color-surface: #2b3a38bf;
134
- --color-on-surface: #dde4e3;
135
- --color-on-surface-variant: #dde4e380;
136
- --color-surface-container: #262d2d;
137
-
138
- --color-border: #889392;
139
- --color-scrim: rgba(0, 0, 0, 0.25);
140
-
141
- --color-shadow-l: rgba(255, 255, 255, 0.25);
142
- --color-shadow-d: rgba(0, 0, 0, 1);
143
-
144
- /* ===== Effect ===== */
145
- --blur: blur(8px);
146
-
147
- --shadow-sm:
148
- -2px -2px 2px var(--color-shadow-l), 2px 2px 2px 1px var(--color-shadow-d);
149
-
150
- --shadow-sm-in:
151
- inset -2px -2px 2px var(--color-shadow-l),
152
- inset 2px 2px 2px var(--color-shadow-d);
153
-
154
- --shadow-md:
155
- -2px -2px 4px 2px var(--color-shadow-l),
156
- 2px 2px 4px 2px var(--color-shadow-d);
157
-
158
- --shadow-md-in:
159
- inset -4px -4px 4px var(--color-shadow-l),
160
- inset 4px 4px 4px var(--color-shadow-d);
161
-
162
- --shadow-lg:
163
- -4px -4px 16px 8px var(--color-shadow-l),
164
- 4px 4px 16px 8px var(--color-shadow-d);
165
- }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lucentia-ui",
3
- "version": "0.2.12",
3
+ "version": "0.2.13",
4
4
  "description": "React UI design token and component system based on neumorphism, featuring two color themes: light and dark.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -9,7 +9,7 @@
9
9
  "import": "./dist/index.js",
10
10
  "types": "./dist/index.d.ts"
11
11
  },
12
- "./styles/styles": "./dist/styles/styles.css",
12
+ "./styles": "./dist/styles/styles.css",
13
13
  "./styles/tokens": "./dist/styles/tokens.css",
14
14
  "./styles/base": "./dist/styles/base.css",
15
15
  "./styles/font": "./dist/styles/font.css"