@kkcompany/app-ui 0.1.21 → 0.1.23

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/dist/index.cjs CHANGED
@@ -1,6 +1,302 @@
1
+ let __emotion_react = require("@emotion/react");
1
2
  let react = require("react");
2
3
  let __emotion_react_jsx_runtime = require("@emotion/react/jsx-runtime");
3
4
 
5
+ //#region src/Dropdown.tsx
6
+ /** @jsxImportSource @emotion/react */
7
+ const dropdownStyle = __emotion_react.css`
8
+ .text-truncate {
9
+ display: block;
10
+ width: 100%;
11
+ text-align: left;
12
+ white-space: nowrap;
13
+ overflow: hidden;
14
+ text-overflow: ellipsis;
15
+ }
16
+
17
+ .font {
18
+ font-size: 1rem;
19
+ font-weight: normal;
20
+ line-height: 1.25;
21
+ }
22
+
23
+ .icon {
24
+ margin-left: 0.5rem;
25
+ background-size: 100%;
26
+ background-position: center;
27
+ background-repeat: no-repeat;
28
+ width: 0.9rem;
29
+ height: 0.9rem;
30
+ }
31
+
32
+ .item-row {
33
+ display: flex;
34
+ justify-content: space-between;
35
+ align-items: center;
36
+ }
37
+
38
+ .kks-dropdown__btn {
39
+ padding: 1px 8px;
40
+ width: 100%;
41
+ height: 2rem;
42
+ border: 1px solid;
43
+ border-radius: 4px;
44
+ background: #f1f1f1;
45
+ outline: none;
46
+
47
+ &--disabled {
48
+ opacity: 0.5;
49
+ }
50
+
51
+ .kks-dropdown__label--grey-off {
52
+ opacity: 0.5;
53
+ }
54
+
55
+ .kks-dropdown__arrow-icon {
56
+ background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJDYXBhXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iMzA2cHgiIGhlaWdodD0iMzA2cHgiIHZpZXdCb3g9IjAgMCAzMDYgMzA2IiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAzMDYgMzA2OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PGc+PGcgaWQ9ImV4cGFuZC1tb3JlIj48cG9seWdvbiBwb2ludHM9IjI3MC4zLDU4LjY1IDE1MywxNzUuOTUgMzUuNyw1OC42NSAwLDk0LjM1IDE1MywyNDcuMzUgMzA2LDk0LjM1ICIvPjwvZz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PC9zdmc+");
57
+ }
58
+ }
59
+
60
+ .kks-dropdown__menu-overlay {
61
+ position: fixed;
62
+ top: 0;
63
+ right: 0;
64
+ bottom: 0;
65
+ left: 0;
66
+ display: flex;
67
+ justify-content: center;
68
+ align-items: center;
69
+ outline: none;
70
+ background: rgba(0, 0, 0, 0.5);
71
+ animation: fade-in 0.15s linear;
72
+ z-index: 1000;
73
+
74
+ .kks-dropdown__menu {
75
+ width: 92%;
76
+ border-radius: $dropdown-border-radius;
77
+ background: #fff;
78
+ overflow: hidden;
79
+ }
80
+
81
+ .kks-dropdown__menu-header {
82
+ height: 2.5rem;
83
+ border-bottom: 1px solid #e9ecef;
84
+
85
+ .kks-dropdown__menu-title {
86
+ margin-left: $item-row-elem-margin-x-sm;
87
+ font-size: 1.25rem;
88
+ }
89
+
90
+ .kks-dropdown__close-btn {
91
+ display: flex;
92
+ align-items: center;
93
+ margin-left: auto;
94
+ padding: 0 $item-row-elem-margin-x-sm;
95
+ height: 100%;
96
+ outline: none;
97
+ }
98
+
99
+ .kks-dropdown__close-icon {
100
+ display: block;
101
+ margin-left: 0;
102
+ background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJDYXBhXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iMzU3cHgiIGhlaWdodD0iMzU3cHgiIHZpZXdCb3g9IjAgMCAzNTcgMzU3IiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAzNTcgMzU3OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PGc+PGcgaWQ9ImNsb3NlIj48cG9seWdvbiBwb2ludHM9IjM1NywzNS43IDMyMS4zLDAgMTc4LjUsMTQyLjggMzUuNywwIDAsMzUuNyAxNDIuOCwxNzguNSAwLDMyMS4zIDM1LjcsMzU3IDE3OC41LDIxNC4yIDMyMS4zLDM1NyAzNTcsMzIxLjMgMjE0LjIsMTc4LjUgIi8+PC9nPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48L3N2Zz4=");
103
+ }
104
+ }
105
+
106
+ .kks-dropdown__menu-body {
107
+ margin: 0;
108
+ padding: 7px 0;
109
+ max-height: 70vh;
110
+ list-style: none;
111
+ overflow-y: auto;
112
+
113
+ .kks-dropdown__menu-link {
114
+ padding: 10px $item-row-elem-margin-x-sm;
115
+ text-decoration: none;
116
+ color: #000;
117
+ outline: none;
118
+ }
119
+
120
+ .kks-dropdown__check-icon {
121
+ background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJDYXBhXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iNzguMzY5cHgiIGhlaWdodD0iNzguMzY5cHgiIHZpZXdCb3g9IjAgMCA3OC4zNjkgNzguMzY5IiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA3OC4zNjkgNzguMzY5OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PGc+PHBhdGggZD0iTTc4LjA0OSwxOS4wMTVMMjkuNDU4LDY3LjYwNmMtMC40MjgsMC40MjgtMS4xMjEsMC40MjgtMS41NDgsMEwwLjMyLDQwLjAxNWMtMC40MjctMC40MjYtMC40MjctMS4xMTksMC0xLjU0N2w2LjcwNC02LjcwNGMwLjQyOC0wLjQyNywxLjEyMS0wLjQyNywxLjU0OCwwbDIwLjExMywyMC4xMTJsNDEuMTEzLTQxLjExM2MwLjQyOS0wLjQyNywxLjEyLTAuNDI3LDEuNTQ4LDBsNi43MDMsNi43MDRDNzguNDc3LDE3Ljg5NCw3OC40NzcsMTguNTg2LDc4LjA0OSwxOS4wMTV6Ii8+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjwvc3ZnPg==");
122
+ }
123
+ }
124
+ }
125
+
126
+ @media only screen and (min-width: 768px) {
127
+ display: inline-block;
128
+
129
+ .kks-dropdown__btn,
130
+ .kks-dropdown__menu {
131
+ min-width: 12rem;
132
+ }
133
+
134
+ .kks-dropdown__btn {
135
+ cursor: pointer;
136
+
137
+ &:focus,
138
+ &:hover:not(:disabled) {
139
+ background: #fff;
140
+ }
141
+
142
+ &--disabled {
143
+ cursor: auto;
144
+ }
145
+ }
146
+
147
+ .kks-dropdown__menu-overlay {
148
+ position: absolute;
149
+ top: auto;
150
+ right: auto;
151
+ bottom: auto;
152
+ left: auto;
153
+ padding: 6px 0;
154
+ background: transparent;
155
+ z-index: 30;
156
+
157
+ .kks-dropdown__menu {
158
+ width: 100%;
159
+ background: #eee;
160
+ }
161
+
162
+ .kks-dropdown__menu-header {
163
+ display: none;
164
+ }
165
+
166
+ .kks-dropdown__menu-body {
167
+ padding: 5px 0;
168
+ max-height: 60vh;
169
+
170
+ .kks-dropdown__menu-link {
171
+ padding: 5px 10px;
172
+ cursor: pointer;
173
+
174
+ &:focus,
175
+ &:hover {
176
+ background: #cacaca;
177
+ }
178
+ }
179
+ }
180
+ }
181
+ }
182
+
183
+ @keyframes fade-in {
184
+ from {
185
+ opacity: 0;
186
+ }
187
+ to {
188
+ opacity: 1;
189
+ }
190
+ }
191
+ `;
192
+ const Button = ({ showMenu, label, placeholder, disabled, onClick }) => /* @__PURE__ */ (0, __emotion_react_jsx_runtime.jsxs)("button", {
193
+ className: `item-row kks-dropdown__btn${disabled ? " kks-dropdown__btn--disabled" : ""}`,
194
+ onClick,
195
+ type: "button",
196
+ "aria-haspopup": "true",
197
+ "aria-expanded": showMenu,
198
+ disabled,
199
+ children: [/* @__PURE__ */ (0, __emotion_react_jsx_runtime.jsx)("span", {
200
+ className: `font text-truncate${!label ? " kks-dropdown__label--grey-off" : ""}`,
201
+ children: !label ? placeholder : label
202
+ }), /* @__PURE__ */ (0, __emotion_react_jsx_runtime.jsx)("span", { className: "icon kks-dropdown__arrow-icon" })]
203
+ });
204
+ const Menu = ({ menuTitle, items, activeIndex = -1, onClickItem, onClickClose }) => {
205
+ const menuRef = (0, react.useRef)(null);
206
+ (0, react.useEffect)(() => {
207
+ if (menuRef.current && !/(?:\b(MS)?IE\s+|\bTrident\/7\.0;.*\s+rv:|\bEdge\/)(\d+)/.test(window.navigator.userAgent)) menuRef.current.scrollIntoView({ block: "nearest" });
208
+ }, []);
209
+ const handleOverlayClick = (e) => {
210
+ if (e.target.id === "kks-menu-overlay") onClickClose();
211
+ };
212
+ return /* @__PURE__ */ (0, __emotion_react_jsx_runtime.jsx)("div", {
213
+ id: "kks-menu-overlay",
214
+ className: "kks-dropdown__menu-overlay",
215
+ onClick: handleOverlayClick,
216
+ tabIndex: -1,
217
+ "aria-hidden": "true",
218
+ ref: menuRef,
219
+ children: /* @__PURE__ */ (0, __emotion_react_jsx_runtime.jsxs)("div", {
220
+ className: "kks-dropdown__menu",
221
+ children: [/* @__PURE__ */ (0, __emotion_react_jsx_runtime.jsxs)("div", {
222
+ className: "item-row kks-dropdown__menu-header",
223
+ children: [menuTitle !== "" && /* @__PURE__ */ (0, __emotion_react_jsx_runtime.jsx)("div", {
224
+ className: "font text-truncate kks-dropdown__menu-title",
225
+ children: menuTitle
226
+ }), /* @__PURE__ */ (0, __emotion_react_jsx_runtime.jsx)("div", {
227
+ className: "kks-dropdown__close-btn",
228
+ onClick: onClickClose,
229
+ onKeyPress: onClickClose,
230
+ role: "button",
231
+ tabIndex: 0,
232
+ children: /* @__PURE__ */ (0, __emotion_react_jsx_runtime.jsx)("span", { className: "icon kks-dropdown__close-icon" })
233
+ })]
234
+ }), /* @__PURE__ */ (0, __emotion_react_jsx_runtime.jsx)("ul", {
235
+ className: "kks-dropdown__menu-body",
236
+ children: items.map((item, index) => {
237
+ const { id, label, route, value } = item;
238
+ const isActive = activeIndex === index;
239
+ return /* @__PURE__ */ (0, __emotion_react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, __emotion_react_jsx_runtime.jsxs)("a", {
240
+ href: route || "#",
241
+ onClick: onClickItem(item, index),
242
+ "data-value": value,
243
+ children: [/* @__PURE__ */ (0, __emotion_react_jsx_runtime.jsx)("span", { children: label || value }), isActive && /* @__PURE__ */ (0, __emotion_react_jsx_runtime.jsx)("span", {})]
244
+ }) }, `item_${id || value || index}`);
245
+ })
246
+ })]
247
+ })
248
+ });
249
+ };
250
+ const Dropdown = ({ className, options = [], value = null, activeIndex = -1, placeholder = "", disabled = false, menuTitle = "", nextRouter = null, onChange = () => {} }) => {
251
+ const dropdownRef = (0, react.useRef)(null);
252
+ const [showMenu, setShowMenu] = (0, react.useState)(false);
253
+ (0, react.useEffect)(() => {
254
+ if (!options.length) return;
255
+ const handleClickOutside = (e) => {
256
+ if (dropdownRef.current && !dropdownRef.current.contains(e.target)) setShowMenu(false);
257
+ };
258
+ window.addEventListener("mousedown", handleClickOutside);
259
+ return () => window.removeEventListener("mousedown", handleClickOutside);
260
+ }, [options.length]);
261
+ const toggleMenu = () => {
262
+ setShowMenu((prev) => !prev);
263
+ };
264
+ const handleMenuItemClick = (option, index) => (e) => {
265
+ e.preventDefault();
266
+ const { route, routeParams = {}, routeOptions = {} } = option;
267
+ if (nextRouter && route) nextRouter.pushRoute(route, routeParams, routeOptions);
268
+ onChange({
269
+ option,
270
+ index
271
+ });
272
+ toggleMenu();
273
+ };
274
+ if (!options.length) return null;
275
+ let selectedIndex = options.findIndex((item) => value && item.value === value);
276
+ if (selectedIndex === -1) selectedIndex = activeIndex;
277
+ const selectedOption = options[selectedIndex];
278
+ return /* @__PURE__ */ (0, __emotion_react_jsx_runtime.jsxs)("div", {
279
+ css: dropdownStyle,
280
+ className,
281
+ ref: dropdownRef,
282
+ children: [/* @__PURE__ */ (0, __emotion_react_jsx_runtime.jsx)(Button, {
283
+ showMenu,
284
+ label: selectedOption?.label || selectedOption?.value,
285
+ placeholder,
286
+ disabled,
287
+ onClick: toggleMenu
288
+ }), showMenu && /* @__PURE__ */ (0, __emotion_react_jsx_runtime.jsx)(Menu, {
289
+ menuTitle,
290
+ items: options,
291
+ activeIndex: selectedIndex,
292
+ onClickItem: handleMenuItemClick,
293
+ onClickClose: toggleMenu
294
+ })]
295
+ });
296
+ };
297
+ var Dropdown_default = Dropdown;
298
+
299
+ //#endregion
4
300
  //#region src/HiddenToggle.tsx
5
301
  const toggleStyle = {
6
302
  "-webkit-tap-highlight-color": "transparent",
@@ -246,17 +542,14 @@ const tagBaseStyles = {
246
542
  gap: "0.4em",
247
543
  color: "var(--tag-color)",
248
544
  justifyContent: "var(--tag-justify-content, flex-start)",
249
- fontSize: "10px",
545
+ fontSize: "calc(0.75rem * 5 / 6)",
250
546
  wordBreak: "keep-all",
251
547
  "> div": {
252
- padding: "0.3em 0.6em",
253
- borderRadius: "2px",
548
+ padding: "0.4em 0.6em",
549
+ borderRadius: "0.2em",
254
550
  fontWeight: 600,
255
551
  background: "var(--tag-background)",
256
- boxShadow: "0 2px 4px 0 rgba(0,0,0,0.25)",
257
- minHeight: "15px",
258
- display: "flex",
259
- alignItems: "center"
552
+ boxShadow: "0 2px 4px 0 rgba(0,0,0,0.25)"
260
553
  }
261
554
  }
262
555
  };
@@ -265,10 +558,6 @@ const tagBottomStyles = {
265
558
  "--tag-color": "#000",
266
559
  "--tag-background": "#fff"
267
560
  };
268
- const newTagStyles = { minWidth: "26px" };
269
- const onSaleTagStyles = { minWidth: "40px" };
270
- const freeTagStyles = { minWidth: "20px" };
271
- const megaTagStyles = { minWidth: "30px" };
272
561
  const VideoThumbnail = ({ href, imageUrl, title, progress, topTags = [], bottomTags = [], children, slots = {}, onClick }) => {
273
562
  const components = {
274
563
  Link: "a",
@@ -297,19 +586,9 @@ const VideoThumbnail = ({ href, imageUrl, title, progress, topTags = [], bottomT
297
586
  }),
298
587
  /* @__PURE__ */ (0, __emotion_react_jsx_runtime.jsxs)("div", {
299
588
  css: tagBaseStyles,
300
- children: [/* @__PURE__ */ (0, __emotion_react_jsx_runtime.jsx)("div", { children: topTags?.map((tag) => /* @__PURE__ */ (0, __emotion_react_jsx_runtime.jsx)("div", {
301
- css: [
302
- tag === "NEW" && newTagStyles,
303
- tag === "セール中" && onSaleTagStyles,
304
- tag === "無料" && freeTagStyles
305
- ],
306
- children: tag
307
- }, tag)) }), bottomTags.length > 0 && /* @__PURE__ */ (0, __emotion_react_jsx_runtime.jsx)("div", {
589
+ children: [/* @__PURE__ */ (0, __emotion_react_jsx_runtime.jsx)("div", { children: topTags?.map((tag) => /* @__PURE__ */ (0, __emotion_react_jsx_runtime.jsx)("div", { children: tag }, tag)) }), bottomTags.length > 0 && /* @__PURE__ */ (0, __emotion_react_jsx_runtime.jsx)("div", {
308
590
  css: [tagBottomStyles, progress >= 0 && { marginBottom: "8px" }],
309
- children: bottomTags?.map((tag) => /* @__PURE__ */ (0, __emotion_react_jsx_runtime.jsx)("div", {
310
- css: [tag === "見放題" && megaTagStyles],
311
- children: tag
312
- }, tag))
591
+ children: bottomTags?.map((tag) => /* @__PURE__ */ (0, __emotion_react_jsx_runtime.jsx)("div", { children: tag }, tag))
313
592
  })]
314
593
  })
315
594
  ]
@@ -439,6 +718,7 @@ const VideoItem = ({ style, href = "", thumbnailHref = href, imageUrl = "", data
439
718
  var VideoItem_default = VideoItem;
440
719
 
441
720
  //#endregion
721
+ exports.Dropdown = Dropdown_default;
442
722
  exports.HiddenToggle = HiddenToggle_default;
443
723
  exports.Icon = Icon_default;
444
724
  exports.SeeMore = SeeMore_default;
package/dist/index.d.cts CHANGED
@@ -1,8 +1,45 @@
1
- import * as _emotion_react_jsx_runtime2 from "@emotion/react/jsx-runtime";
2
- import { CSSObject } from "@emotion/react";
3
1
  import { ElementType, MouseEventHandler, ReactElement, ReactNode } from "react";
2
+ import * as _emotion_react_jsx_runtime0 from "@emotion/react/jsx-runtime";
3
+ import { CSSObject } from "@emotion/react";
4
4
  import Link from "next/link";
5
5
 
6
+ //#region src/Dropdown.d.ts
7
+ type DropdownOption = {
8
+ id?: string | number;
9
+ label?: string | number;
10
+ value: string | number;
11
+ route?: string;
12
+ routeParams?: Record<string, unknown>;
13
+ routeOptions?: Record<string, unknown>;
14
+ };
15
+ type NextRouter = {
16
+ pushRoute: (route: string, routeParams?: Record<string, unknown>, routeOptions?: Record<string, unknown>) => void;
17
+ };
18
+ declare const Dropdown: ({
19
+ className,
20
+ options,
21
+ value,
22
+ activeIndex,
23
+ placeholder,
24
+ disabled,
25
+ menuTitle,
26
+ nextRouter,
27
+ onChange
28
+ }: {
29
+ className?: string;
30
+ options?: DropdownOption[];
31
+ value?: string | number | null;
32
+ activeIndex?: number;
33
+ placeholder?: string;
34
+ disabled?: boolean;
35
+ menuTitle?: string;
36
+ nextRouter?: NextRouter | null;
37
+ onChange?: (payload: {
38
+ option: DropdownOption;
39
+ index: number;
40
+ }) => void;
41
+ }) => ReactElement | null;
42
+ //#endregion
6
43
  //#region src/HiddenToggle.d.ts
7
44
  /** @jsxImportSource @emotion/react */
8
45
  /** biome-ignore-all lint/a11y/useKeyWithClickEvents: <explanation> */
@@ -17,7 +54,7 @@ declare const HiddenToggle: ({
17
54
  defaultEnabled?: boolean;
18
55
  children: any;
19
56
  onChange: any;
20
- }) => _emotion_react_jsx_runtime2.JSX.Element;
57
+ }) => _emotion_react_jsx_runtime0.JSX.Element;
21
58
  //#endregion
22
59
  //#region src/Icon.d.ts
23
60
  declare const Icon: ({
@@ -26,7 +63,7 @@ declare const Icon: ({
26
63
  }: {
27
64
  style?: {};
28
65
  src: any;
29
- }) => _emotion_react_jsx_runtime2.JSX.Element;
66
+ }) => _emotion_react_jsx_runtime0.JSX.Element;
30
67
  //#endregion
31
68
  //#region src/SeeMore.d.ts
32
69
  declare const defaultMessages: {
@@ -42,7 +79,7 @@ declare const SeeMore: ({
42
79
  style?: CSSObject;
43
80
  messages?: typeof defaultMessages;
44
81
  children?: ReactNode;
45
- }) => _emotion_react_jsx_runtime2.JSX.Element;
82
+ }) => _emotion_react_jsx_runtime0.JSX.Element;
46
83
  //#endregion
47
84
  //#region src/VideoItem.d.ts
48
85
  type VideoDetail = {
@@ -106,6 +143,6 @@ declare const VideoThumbnail: ({
106
143
  Image?: ElementType;
107
144
  };
108
145
  onClick?: MouseEventHandler<HTMLAnchorElement>;
109
- }) => _emotion_react_jsx_runtime2.JSX.Element;
146
+ }) => _emotion_react_jsx_runtime0.JSX.Element;
110
147
  //#endregion
111
- export { HiddenToggle, Icon, SeeMore, VideoItem, VideoThumbnail };
148
+ export { Dropdown, HiddenToggle, Icon, SeeMore, VideoItem, VideoThumbnail };
package/dist/index.d.mts CHANGED
@@ -1,8 +1,45 @@
1
+ import { CSSObject } from "@emotion/react";
1
2
  import { ElementType, MouseEventHandler, ReactElement, ReactNode } from "react";
2
3
  import * as _emotion_react_jsx_runtime0 from "@emotion/react/jsx-runtime";
3
- import { CSSObject } from "@emotion/react";
4
4
  import Link from "next/link";
5
5
 
6
+ //#region src/Dropdown.d.ts
7
+ type DropdownOption = {
8
+ id?: string | number;
9
+ label?: string | number;
10
+ value: string | number;
11
+ route?: string;
12
+ routeParams?: Record<string, unknown>;
13
+ routeOptions?: Record<string, unknown>;
14
+ };
15
+ type NextRouter = {
16
+ pushRoute: (route: string, routeParams?: Record<string, unknown>, routeOptions?: Record<string, unknown>) => void;
17
+ };
18
+ declare const Dropdown: ({
19
+ className,
20
+ options,
21
+ value,
22
+ activeIndex,
23
+ placeholder,
24
+ disabled,
25
+ menuTitle,
26
+ nextRouter,
27
+ onChange
28
+ }: {
29
+ className?: string;
30
+ options?: DropdownOption[];
31
+ value?: string | number | null;
32
+ activeIndex?: number;
33
+ placeholder?: string;
34
+ disabled?: boolean;
35
+ menuTitle?: string;
36
+ nextRouter?: NextRouter | null;
37
+ onChange?: (payload: {
38
+ option: DropdownOption;
39
+ index: number;
40
+ }) => void;
41
+ }) => ReactElement | null;
42
+ //#endregion
6
43
  //#region src/HiddenToggle.d.ts
7
44
  /** @jsxImportSource @emotion/react */
8
45
  /** biome-ignore-all lint/a11y/useKeyWithClickEvents: <explanation> */
@@ -108,4 +145,4 @@ declare const VideoThumbnail: ({
108
145
  onClick?: MouseEventHandler<HTMLAnchorElement>;
109
146
  }) => _emotion_react_jsx_runtime0.JSX.Element;
110
147
  //#endregion
111
- export { HiddenToggle, Icon, SeeMore, VideoItem, VideoThumbnail };
148
+ export { Dropdown, HiddenToggle, Icon, SeeMore, VideoItem, VideoThumbnail };
package/dist/index.mjs CHANGED
@@ -1,6 +1,302 @@
1
+ import { css } from "@emotion/react";
1
2
  import { useEffect, useRef, useState } from "react";
2
3
  import { jsx, jsxs } from "@emotion/react/jsx-runtime";
3
4
 
5
+ //#region src/Dropdown.tsx
6
+ /** @jsxImportSource @emotion/react */
7
+ const dropdownStyle = css`
8
+ .text-truncate {
9
+ display: block;
10
+ width: 100%;
11
+ text-align: left;
12
+ white-space: nowrap;
13
+ overflow: hidden;
14
+ text-overflow: ellipsis;
15
+ }
16
+
17
+ .font {
18
+ font-size: 1rem;
19
+ font-weight: normal;
20
+ line-height: 1.25;
21
+ }
22
+
23
+ .icon {
24
+ margin-left: 0.5rem;
25
+ background-size: 100%;
26
+ background-position: center;
27
+ background-repeat: no-repeat;
28
+ width: 0.9rem;
29
+ height: 0.9rem;
30
+ }
31
+
32
+ .item-row {
33
+ display: flex;
34
+ justify-content: space-between;
35
+ align-items: center;
36
+ }
37
+
38
+ .kks-dropdown__btn {
39
+ padding: 1px 8px;
40
+ width: 100%;
41
+ height: 2rem;
42
+ border: 1px solid;
43
+ border-radius: 4px;
44
+ background: #f1f1f1;
45
+ outline: none;
46
+
47
+ &--disabled {
48
+ opacity: 0.5;
49
+ }
50
+
51
+ .kks-dropdown__label--grey-off {
52
+ opacity: 0.5;
53
+ }
54
+
55
+ .kks-dropdown__arrow-icon {
56
+ background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJDYXBhXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iMzA2cHgiIGhlaWdodD0iMzA2cHgiIHZpZXdCb3g9IjAgMCAzMDYgMzA2IiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAzMDYgMzA2OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PGc+PGcgaWQ9ImV4cGFuZC1tb3JlIj48cG9seWdvbiBwb2ludHM9IjI3MC4zLDU4LjY1IDE1MywxNzUuOTUgMzUuNyw1OC42NSAwLDk0LjM1IDE1MywyNDcuMzUgMzA2LDk0LjM1ICIvPjwvZz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PC9zdmc+");
57
+ }
58
+ }
59
+
60
+ .kks-dropdown__menu-overlay {
61
+ position: fixed;
62
+ top: 0;
63
+ right: 0;
64
+ bottom: 0;
65
+ left: 0;
66
+ display: flex;
67
+ justify-content: center;
68
+ align-items: center;
69
+ outline: none;
70
+ background: rgba(0, 0, 0, 0.5);
71
+ animation: fade-in 0.15s linear;
72
+ z-index: 1000;
73
+
74
+ .kks-dropdown__menu {
75
+ width: 92%;
76
+ border-radius: $dropdown-border-radius;
77
+ background: #fff;
78
+ overflow: hidden;
79
+ }
80
+
81
+ .kks-dropdown__menu-header {
82
+ height: 2.5rem;
83
+ border-bottom: 1px solid #e9ecef;
84
+
85
+ .kks-dropdown__menu-title {
86
+ margin-left: $item-row-elem-margin-x-sm;
87
+ font-size: 1.25rem;
88
+ }
89
+
90
+ .kks-dropdown__close-btn {
91
+ display: flex;
92
+ align-items: center;
93
+ margin-left: auto;
94
+ padding: 0 $item-row-elem-margin-x-sm;
95
+ height: 100%;
96
+ outline: none;
97
+ }
98
+
99
+ .kks-dropdown__close-icon {
100
+ display: block;
101
+ margin-left: 0;
102
+ background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJDYXBhXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iMzU3cHgiIGhlaWdodD0iMzU3cHgiIHZpZXdCb3g9IjAgMCAzNTcgMzU3IiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAzNTcgMzU3OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PGc+PGcgaWQ9ImNsb3NlIj48cG9seWdvbiBwb2ludHM9IjM1NywzNS43IDMyMS4zLDAgMTc4LjUsMTQyLjggMzUuNywwIDAsMzUuNyAxNDIuOCwxNzguNSAwLDMyMS4zIDM1LjcsMzU3IDE3OC41LDIxNC4yIDMyMS4zLDM1NyAzNTcsMzIxLjMgMjE0LjIsMTc4LjUgIi8+PC9nPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48L3N2Zz4=");
103
+ }
104
+ }
105
+
106
+ .kks-dropdown__menu-body {
107
+ margin: 0;
108
+ padding: 7px 0;
109
+ max-height: 70vh;
110
+ list-style: none;
111
+ overflow-y: auto;
112
+
113
+ .kks-dropdown__menu-link {
114
+ padding: 10px $item-row-elem-margin-x-sm;
115
+ text-decoration: none;
116
+ color: #000;
117
+ outline: none;
118
+ }
119
+
120
+ .kks-dropdown__check-icon {
121
+ background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJDYXBhXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iNzguMzY5cHgiIGhlaWdodD0iNzguMzY5cHgiIHZpZXdCb3g9IjAgMCA3OC4zNjkgNzguMzY5IiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA3OC4zNjkgNzguMzY5OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PGc+PHBhdGggZD0iTTc4LjA0OSwxOS4wMTVMMjkuNDU4LDY3LjYwNmMtMC40MjgsMC40MjgtMS4xMjEsMC40MjgtMS41NDgsMEwwLjMyLDQwLjAxNWMtMC40MjctMC40MjYtMC40MjctMS4xMTksMC0xLjU0N2w2LjcwNC02LjcwNGMwLjQyOC0wLjQyNywxLjEyMS0wLjQyNywxLjU0OCwwbDIwLjExMywyMC4xMTJsNDEuMTEzLTQxLjExM2MwLjQyOS0wLjQyNywxLjEyLTAuNDI3LDEuNTQ4LDBsNi43MDMsNi43MDRDNzguNDc3LDE3Ljg5NCw3OC40NzcsMTguNTg2LDc4LjA0OSwxOS4wMTV6Ii8+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjwvc3ZnPg==");
122
+ }
123
+ }
124
+ }
125
+
126
+ @media only screen and (min-width: 768px) {
127
+ display: inline-block;
128
+
129
+ .kks-dropdown__btn,
130
+ .kks-dropdown__menu {
131
+ min-width: 12rem;
132
+ }
133
+
134
+ .kks-dropdown__btn {
135
+ cursor: pointer;
136
+
137
+ &:focus,
138
+ &:hover:not(:disabled) {
139
+ background: #fff;
140
+ }
141
+
142
+ &--disabled {
143
+ cursor: auto;
144
+ }
145
+ }
146
+
147
+ .kks-dropdown__menu-overlay {
148
+ position: absolute;
149
+ top: auto;
150
+ right: auto;
151
+ bottom: auto;
152
+ left: auto;
153
+ padding: 6px 0;
154
+ background: transparent;
155
+ z-index: 30;
156
+
157
+ .kks-dropdown__menu {
158
+ width: 100%;
159
+ background: #eee;
160
+ }
161
+
162
+ .kks-dropdown__menu-header {
163
+ display: none;
164
+ }
165
+
166
+ .kks-dropdown__menu-body {
167
+ padding: 5px 0;
168
+ max-height: 60vh;
169
+
170
+ .kks-dropdown__menu-link {
171
+ padding: 5px 10px;
172
+ cursor: pointer;
173
+
174
+ &:focus,
175
+ &:hover {
176
+ background: #cacaca;
177
+ }
178
+ }
179
+ }
180
+ }
181
+ }
182
+
183
+ @keyframes fade-in {
184
+ from {
185
+ opacity: 0;
186
+ }
187
+ to {
188
+ opacity: 1;
189
+ }
190
+ }
191
+ `;
192
+ const Button = ({ showMenu, label, placeholder, disabled, onClick }) => /* @__PURE__ */ jsxs("button", {
193
+ className: `item-row kks-dropdown__btn${disabled ? " kks-dropdown__btn--disabled" : ""}`,
194
+ onClick,
195
+ type: "button",
196
+ "aria-haspopup": "true",
197
+ "aria-expanded": showMenu,
198
+ disabled,
199
+ children: [/* @__PURE__ */ jsx("span", {
200
+ className: `font text-truncate${!label ? " kks-dropdown__label--grey-off" : ""}`,
201
+ children: !label ? placeholder : label
202
+ }), /* @__PURE__ */ jsx("span", { className: "icon kks-dropdown__arrow-icon" })]
203
+ });
204
+ const Menu = ({ menuTitle, items, activeIndex = -1, onClickItem, onClickClose }) => {
205
+ const menuRef = useRef(null);
206
+ useEffect(() => {
207
+ if (menuRef.current && !/(?:\b(MS)?IE\s+|\bTrident\/7\.0;.*\s+rv:|\bEdge\/)(\d+)/.test(window.navigator.userAgent)) menuRef.current.scrollIntoView({ block: "nearest" });
208
+ }, []);
209
+ const handleOverlayClick = (e) => {
210
+ if (e.target.id === "kks-menu-overlay") onClickClose();
211
+ };
212
+ return /* @__PURE__ */ jsx("div", {
213
+ id: "kks-menu-overlay",
214
+ className: "kks-dropdown__menu-overlay",
215
+ onClick: handleOverlayClick,
216
+ tabIndex: -1,
217
+ "aria-hidden": "true",
218
+ ref: menuRef,
219
+ children: /* @__PURE__ */ jsxs("div", {
220
+ className: "kks-dropdown__menu",
221
+ children: [/* @__PURE__ */ jsxs("div", {
222
+ className: "item-row kks-dropdown__menu-header",
223
+ children: [menuTitle !== "" && /* @__PURE__ */ jsx("div", {
224
+ className: "font text-truncate kks-dropdown__menu-title",
225
+ children: menuTitle
226
+ }), /* @__PURE__ */ jsx("div", {
227
+ className: "kks-dropdown__close-btn",
228
+ onClick: onClickClose,
229
+ onKeyPress: onClickClose,
230
+ role: "button",
231
+ tabIndex: 0,
232
+ children: /* @__PURE__ */ jsx("span", { className: "icon kks-dropdown__close-icon" })
233
+ })]
234
+ }), /* @__PURE__ */ jsx("ul", {
235
+ className: "kks-dropdown__menu-body",
236
+ children: items.map((item, index) => {
237
+ const { id, label, route, value } = item;
238
+ const isActive = activeIndex === index;
239
+ return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs("a", {
240
+ href: route || "#",
241
+ onClick: onClickItem(item, index),
242
+ "data-value": value,
243
+ children: [/* @__PURE__ */ jsx("span", { children: label || value }), isActive && /* @__PURE__ */ jsx("span", {})]
244
+ }) }, `item_${id || value || index}`);
245
+ })
246
+ })]
247
+ })
248
+ });
249
+ };
250
+ const Dropdown = ({ className, options = [], value = null, activeIndex = -1, placeholder = "", disabled = false, menuTitle = "", nextRouter = null, onChange = () => {} }) => {
251
+ const dropdownRef = useRef(null);
252
+ const [showMenu, setShowMenu] = useState(false);
253
+ useEffect(() => {
254
+ if (!options.length) return;
255
+ const handleClickOutside = (e) => {
256
+ if (dropdownRef.current && !dropdownRef.current.contains(e.target)) setShowMenu(false);
257
+ };
258
+ window.addEventListener("mousedown", handleClickOutside);
259
+ return () => window.removeEventListener("mousedown", handleClickOutside);
260
+ }, [options.length]);
261
+ const toggleMenu = () => {
262
+ setShowMenu((prev) => !prev);
263
+ };
264
+ const handleMenuItemClick = (option, index) => (e) => {
265
+ e.preventDefault();
266
+ const { route, routeParams = {}, routeOptions = {} } = option;
267
+ if (nextRouter && route) nextRouter.pushRoute(route, routeParams, routeOptions);
268
+ onChange({
269
+ option,
270
+ index
271
+ });
272
+ toggleMenu();
273
+ };
274
+ if (!options.length) return null;
275
+ let selectedIndex = options.findIndex((item) => value && item.value === value);
276
+ if (selectedIndex === -1) selectedIndex = activeIndex;
277
+ const selectedOption = options[selectedIndex];
278
+ return /* @__PURE__ */ jsxs("div", {
279
+ css: dropdownStyle,
280
+ className,
281
+ ref: dropdownRef,
282
+ children: [/* @__PURE__ */ jsx(Button, {
283
+ showMenu,
284
+ label: selectedOption?.label || selectedOption?.value,
285
+ placeholder,
286
+ disabled,
287
+ onClick: toggleMenu
288
+ }), showMenu && /* @__PURE__ */ jsx(Menu, {
289
+ menuTitle,
290
+ items: options,
291
+ activeIndex: selectedIndex,
292
+ onClickItem: handleMenuItemClick,
293
+ onClickClose: toggleMenu
294
+ })]
295
+ });
296
+ };
297
+ var Dropdown_default = Dropdown;
298
+
299
+ //#endregion
4
300
  //#region src/HiddenToggle.tsx
5
301
  const toggleStyle = {
6
302
  "-webkit-tap-highlight-color": "transparent",
@@ -246,17 +542,14 @@ const tagBaseStyles = {
246
542
  gap: "0.4em",
247
543
  color: "var(--tag-color)",
248
544
  justifyContent: "var(--tag-justify-content, flex-start)",
249
- fontSize: "10px",
545
+ fontSize: "calc(0.75rem * 5 / 6)",
250
546
  wordBreak: "keep-all",
251
547
  "> div": {
252
- padding: "0.3em 0.6em",
253
- borderRadius: "2px",
548
+ padding: "0.4em 0.6em",
549
+ borderRadius: "0.2em",
254
550
  fontWeight: 600,
255
551
  background: "var(--tag-background)",
256
- boxShadow: "0 2px 4px 0 rgba(0,0,0,0.25)",
257
- minHeight: "15px",
258
- display: "flex",
259
- alignItems: "center"
552
+ boxShadow: "0 2px 4px 0 rgba(0,0,0,0.25)"
260
553
  }
261
554
  }
262
555
  };
@@ -265,10 +558,6 @@ const tagBottomStyles = {
265
558
  "--tag-color": "#000",
266
559
  "--tag-background": "#fff"
267
560
  };
268
- const newTagStyles = { minWidth: "26px" };
269
- const onSaleTagStyles = { minWidth: "40px" };
270
- const freeTagStyles = { minWidth: "20px" };
271
- const megaTagStyles = { minWidth: "30px" };
272
561
  const VideoThumbnail = ({ href, imageUrl, title, progress, topTags = [], bottomTags = [], children, slots = {}, onClick }) => {
273
562
  const components = {
274
563
  Link: "a",
@@ -297,19 +586,9 @@ const VideoThumbnail = ({ href, imageUrl, title, progress, topTags = [], bottomT
297
586
  }),
298
587
  /* @__PURE__ */ jsxs("div", {
299
588
  css: tagBaseStyles,
300
- children: [/* @__PURE__ */ jsx("div", { children: topTags?.map((tag) => /* @__PURE__ */ jsx("div", {
301
- css: [
302
- tag === "NEW" && newTagStyles,
303
- tag === "セール中" && onSaleTagStyles,
304
- tag === "無料" && freeTagStyles
305
- ],
306
- children: tag
307
- }, tag)) }), bottomTags.length > 0 && /* @__PURE__ */ jsx("div", {
589
+ children: [/* @__PURE__ */ jsx("div", { children: topTags?.map((tag) => /* @__PURE__ */ jsx("div", { children: tag }, tag)) }), bottomTags.length > 0 && /* @__PURE__ */ jsx("div", {
308
590
  css: [tagBottomStyles, progress >= 0 && { marginBottom: "8px" }],
309
- children: bottomTags?.map((tag) => /* @__PURE__ */ jsx("div", {
310
- css: [tag === "見放題" && megaTagStyles],
311
- children: tag
312
- }, tag))
591
+ children: bottomTags?.map((tag) => /* @__PURE__ */ jsx("div", { children: tag }, tag))
313
592
  })]
314
593
  })
315
594
  ]
@@ -439,4 +718,4 @@ const VideoItem = ({ style, href = "", thumbnailHref = href, imageUrl = "", data
439
718
  var VideoItem_default = VideoItem;
440
719
 
441
720
  //#endregion
442
- export { HiddenToggle_default as HiddenToggle, Icon_default as Icon, SeeMore_default as SeeMore, VideoItem_default as VideoItem, VideoThumbnail_default as VideoThumbnail };
721
+ export { Dropdown_default as Dropdown, HiddenToggle_default as HiddenToggle, Icon_default as Icon, SeeMore_default as SeeMore, VideoItem_default as VideoItem, VideoThumbnail_default as VideoThumbnail };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kkcompany/app-ui",
3
- "version": "0.1.21",
3
+ "version": "0.1.23",
4
4
  "module": "dist/index.mjs",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.mts",