cclkit4svelte 1.2.7 → 2.0.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.
- package/README.md +9 -9
- package/dist/Alert.svelte +96 -0
- package/dist/Alert.svelte.d.ts +37 -0
- package/dist/Button.svelte +8 -1
- package/dist/Button.svelte.d.ts +10 -0
- package/dist/Card.svelte +1 -2
- package/dist/Carousel.svelte +2 -4
- package/dist/Checkbox.svelte +88 -0
- package/dist/Checkbox.svelte.d.ts +40 -0
- package/dist/DatePicker.svelte +162 -0
- package/dist/DatePicker.svelte.d.ts +44 -0
- package/dist/FormGroup.svelte +53 -0
- package/dist/FormGroup.svelte.d.ts +37 -0
- package/dist/Input.svelte +107 -0
- package/dist/Input.svelte.d.ts +61 -0
- package/dist/RadioButton.svelte +70 -0
- package/dist/RadioButton.svelte.d.ts +39 -0
- package/dist/Select.svelte +65 -0
- package/dist/Select.svelte.d.ts +48 -0
- package/dist/Table.svelte +1 -2
- package/dist/Textarea.svelte +60 -0
- package/dist/Textarea.svelte.d.ts +56 -0
- package/dist/Toggle.svelte +76 -0
- package/dist/Toggle.svelte.d.ts +35 -0
- package/dist/const/config.js +3 -3
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -0
- package/dist/scripts/date.js +1 -1
- package/package.json +8 -7
package/README.md
CHANGED
|
@@ -28,14 +28,14 @@ CANDY CHUPS Lab.名義でWebサービスを開発したり、ハッカソンに
|
|
|
28
28
|
|
|
29
29
|
## 利用方法
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
利用しているパッケージマネージャーのコマンドでライブラリを導入して下さい。
|
|
32
32
|
|
|
33
33
|
```zsh
|
|
34
|
-
|
|
34
|
+
yarn add cclkit4svelte
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
npm i cclkit4svelte
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
pnpm install cclkit4svelte
|
|
39
39
|
```
|
|
40
40
|
|
|
41
41
|
## 本ライブラリの開発について
|
|
@@ -51,7 +51,7 @@ volta install node@20
|
|
|
51
51
|
|
|
52
52
|
node -v
|
|
53
53
|
#任意のNodeのバージョンが表示されればOK
|
|
54
|
-
|
|
54
|
+
v20.11.1
|
|
55
55
|
```
|
|
56
56
|
|
|
57
57
|
また、本ライブラリの開発には`pnpm`の導入が必要です。`npm`や`yarn`では開発準備ができないためご注意ください。voltaを使用している場合、pnpmもvoltaを使用して導入することができます。
|
|
@@ -94,11 +94,11 @@ Basically, it is not intended to be used by non-CCL members. It is planned to be
|
|
|
94
94
|
Please install the library with the following command.
|
|
95
95
|
|
|
96
96
|
```zsh
|
|
97
|
-
|
|
97
|
+
yarn add cclkit4svelte
|
|
98
98
|
|
|
99
|
-
|
|
99
|
+
npm i cclkit4svelte
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
pnpm install cclkit4svelte
|
|
102
102
|
```
|
|
103
103
|
|
|
104
104
|
## About the development of this library
|
|
@@ -114,7 +114,7 @@ volta install node@20
|
|
|
114
114
|
|
|
115
115
|
node -v
|
|
116
116
|
#Once the desired Node version is displayed, it is OK.
|
|
117
|
-
|
|
117
|
+
v20.11.1
|
|
118
118
|
```
|
|
119
119
|
|
|
120
120
|
Also, you need to install `pnpm` to develop this library. Note that `npm` and `yarn` do not prepare you for development; if you are using volta, pnpm can also be installed using volta.
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
<script>import "./const/variables.css";
|
|
2
|
+
import { CCLVividColor } from "./const/config";
|
|
3
|
+
import { createEventDispatcher } from "svelte";
|
|
4
|
+
const dispatch = createEventDispatcher();
|
|
5
|
+
export let message;
|
|
6
|
+
export let type = "info";
|
|
7
|
+
export let dismissible = false;
|
|
8
|
+
export let outline = false;
|
|
9
|
+
let baseColor;
|
|
10
|
+
let computedBgColor;
|
|
11
|
+
let computedBorderColor;
|
|
12
|
+
let textColor;
|
|
13
|
+
$: {
|
|
14
|
+
switch (type) {
|
|
15
|
+
case "success":
|
|
16
|
+
baseColor = CCLVividColor.MELON_GREEN;
|
|
17
|
+
break;
|
|
18
|
+
case "error":
|
|
19
|
+
baseColor = CCLVividColor.STRAWBERRY_PINK;
|
|
20
|
+
break;
|
|
21
|
+
case "warning":
|
|
22
|
+
baseColor = CCLVividColor.PINEAPPLE_YELLOW;
|
|
23
|
+
break;
|
|
24
|
+
case "info":
|
|
25
|
+
baseColor = CCLVividColor.SODA_BLUE;
|
|
26
|
+
break;
|
|
27
|
+
default:
|
|
28
|
+
baseColor = CCLVividColor.SODA_BLUE;
|
|
29
|
+
}
|
|
30
|
+
if (outline) {
|
|
31
|
+
computedBgColor = "transparent";
|
|
32
|
+
computedBorderColor = baseColor;
|
|
33
|
+
textColor = "var(--wrap-grey)";
|
|
34
|
+
} else {
|
|
35
|
+
computedBgColor = baseColor;
|
|
36
|
+
computedBorderColor = "transparent";
|
|
37
|
+
textColor = "white";
|
|
38
|
+
if (type === "warning") {
|
|
39
|
+
textColor = "white";
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function dismissAlert() {
|
|
44
|
+
dispatch("dismiss");
|
|
45
|
+
}
|
|
46
|
+
</script>
|
|
47
|
+
|
|
48
|
+
<div
|
|
49
|
+
class="alert-wrapper"
|
|
50
|
+
class:dismissible={dismissible}
|
|
51
|
+
class:outline={outline}
|
|
52
|
+
style="background-color: var({computedBgColor}); color: {textColor}; border-color: var({computedBorderColor});"
|
|
53
|
+
>
|
|
54
|
+
<span class="alert-message">{message}</span>
|
|
55
|
+
{#if dismissible}
|
|
56
|
+
<button class="dismiss-button" on:click={dismissAlert} aria-label="Dismiss alert">
|
|
57
|
+
×
|
|
58
|
+
</button>
|
|
59
|
+
{/if}
|
|
60
|
+
</div>
|
|
61
|
+
|
|
62
|
+
<style>
|
|
63
|
+
.alert-wrapper {
|
|
64
|
+
padding: 12px 20px;
|
|
65
|
+
border-radius: 8px;
|
|
66
|
+
display: flex;
|
|
67
|
+
justify-content: space-between;
|
|
68
|
+
align-items: center;
|
|
69
|
+
font-size: 16px;
|
|
70
|
+
font-weight: 500;
|
|
71
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
72
|
+
margin-bottom: 10px; /* Add some spacing when multiple alerts are shown */
|
|
73
|
+
border: 2px solid; /* Use solid border, color set by style attribute */
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.alert-message {
|
|
77
|
+
flex-grow: 1;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.dismiss-button {
|
|
81
|
+
background: none;
|
|
82
|
+
border: none;
|
|
83
|
+
color: inherit; /* Inherit text color from parent */
|
|
84
|
+
font-size: 20px;
|
|
85
|
+
cursor: pointer;
|
|
86
|
+
margin-left: 15px;
|
|
87
|
+
padding: 0;
|
|
88
|
+
line-height: 1;
|
|
89
|
+
opacity: 0.7;
|
|
90
|
+
transition: opacity 0.2s ease-in-out;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.dismiss-button:hover {
|
|
94
|
+
opacity: 1;
|
|
95
|
+
}
|
|
96
|
+
</style>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
import './const/variables.css';
|
|
3
|
+
declare const __propDef: {
|
|
4
|
+
props: {
|
|
5
|
+
/**
|
|
6
|
+
* The message to display in the alert.
|
|
7
|
+
* @type {string}
|
|
8
|
+
*/ message: string;
|
|
9
|
+
/**
|
|
10
|
+
* The type of the alert, which determines its styling.
|
|
11
|
+
* @type {'success' | 'error' | 'warning' | 'info'}
|
|
12
|
+
* @default 'info'
|
|
13
|
+
*/ type?: "success" | "error" | "warning" | "info";
|
|
14
|
+
/**
|
|
15
|
+
* Whether the alert can be dismissed by the user.
|
|
16
|
+
* @type {boolean}
|
|
17
|
+
* @default false
|
|
18
|
+
*/ dismissible?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Whether the alert should have an outline style.
|
|
21
|
+
* @type {boolean}
|
|
22
|
+
* @default false
|
|
23
|
+
*/ outline?: boolean;
|
|
24
|
+
};
|
|
25
|
+
events: {
|
|
26
|
+
dismiss: CustomEvent<any>;
|
|
27
|
+
} & {
|
|
28
|
+
[evt: string]: CustomEvent<any>;
|
|
29
|
+
};
|
|
30
|
+
slots: {};
|
|
31
|
+
};
|
|
32
|
+
export type AlertProps = typeof __propDef.props;
|
|
33
|
+
export type AlertEvents = typeof __propDef.events;
|
|
34
|
+
export type AlertSlots = typeof __propDef.slots;
|
|
35
|
+
export default class Alert extends SvelteComponentTyped<AlertProps, AlertEvents, AlertSlots> {
|
|
36
|
+
}
|
|
37
|
+
export {};
|
package/dist/Button.svelte
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
<script>import "./const/variables.css";
|
|
2
2
|
export let bgColor;
|
|
3
3
|
export let label;
|
|
4
|
+
export let onClick = () => {
|
|
5
|
+
};
|
|
6
|
+
export let disabled = false;
|
|
4
7
|
function getButtonColor(bgColor2) {
|
|
5
8
|
return `var(${bgColor2})`;
|
|
6
9
|
}
|
|
@@ -8,7 +11,7 @@ let buttonColor = getButtonColor(bgColor);
|
|
|
8
11
|
</script>
|
|
9
12
|
|
|
10
13
|
<!--汎用ボタン-->
|
|
11
|
-
<button class="buttonWrapper" style="--bgColor: {buttonColor}">
|
|
14
|
+
<button class="buttonWrapper" style="--bgColor: {buttonColor}" on:click={onClick} {disabled}>
|
|
12
15
|
<span class="btLabel">{label}</span>
|
|
13
16
|
</button>
|
|
14
17
|
|
|
@@ -23,6 +26,10 @@ let buttonColor = getButtonColor(bgColor);
|
|
|
23
26
|
.buttonWrapper:hover {
|
|
24
27
|
cursor: pointer;
|
|
25
28
|
}
|
|
29
|
+
.buttonWrapper:disabled {
|
|
30
|
+
opacity: 0.6;
|
|
31
|
+
cursor: not-allowed;
|
|
32
|
+
}
|
|
26
33
|
.btLabel {
|
|
27
34
|
flex-direction: column;
|
|
28
35
|
justify-content: center;
|
package/dist/Button.svelte.d.ts
CHANGED
|
@@ -12,6 +12,16 @@ declare const __propDef: {
|
|
|
12
12
|
* @default Button
|
|
13
13
|
* @type string
|
|
14
14
|
*/ label: string;
|
|
15
|
+
/**
|
|
16
|
+
* クリックイベントハンドラ
|
|
17
|
+
* @default () => {}
|
|
18
|
+
* @type {() => void}
|
|
19
|
+
*/ onClick?: () => void;
|
|
20
|
+
/**
|
|
21
|
+
* ボタンの非活性状態
|
|
22
|
+
* @default false
|
|
23
|
+
* @type boolean
|
|
24
|
+
*/ disabled?: boolean;
|
|
15
25
|
};
|
|
16
26
|
events: {
|
|
17
27
|
[evt: string]: CustomEvent<any>;
|
package/dist/Card.svelte
CHANGED
|
@@ -23,8 +23,7 @@ function getBodyColor(borderColor2) {
|
|
|
23
23
|
return CCLPastelColor.PEACH_PINK;
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
|
-
$:
|
|
27
|
-
bodyColor = getBodyColor(borderColor);
|
|
26
|
+
$: bodyColor = getBodyColor(borderColor);
|
|
28
27
|
</script>
|
|
29
28
|
|
|
30
29
|
<div class="CardWrapper" style="--border-color: var({borderColor})">
|
package/dist/Carousel.svelte
CHANGED
|
@@ -3,13 +3,11 @@ export let src;
|
|
|
3
3
|
export let csWidth;
|
|
4
4
|
let currentIndex = 0;
|
|
5
5
|
const nextSlide = () => {
|
|
6
|
-
if (src.length === 0)
|
|
7
|
-
return;
|
|
6
|
+
if (src.length === 0) return;
|
|
8
7
|
currentIndex = (currentIndex + 1) % src.length;
|
|
9
8
|
};
|
|
10
9
|
const prevSlide = () => {
|
|
11
|
-
if (src.length === 0)
|
|
12
|
-
return;
|
|
10
|
+
if (src.length === 0) return;
|
|
13
11
|
currentIndex = (currentIndex - 1 + src.length) % src.length;
|
|
14
12
|
};
|
|
15
13
|
</script>
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
<script>import "./const/variables.css";
|
|
2
|
+
import { CCLVividColor } from "./const/config";
|
|
3
|
+
export let label = "";
|
|
4
|
+
export let checked = false;
|
|
5
|
+
export let color = CCLVividColor.SODA_BLUE;
|
|
6
|
+
export let disabled = false;
|
|
7
|
+
export let onChange = () => {
|
|
8
|
+
};
|
|
9
|
+
let checkMarkColor = "white";
|
|
10
|
+
function handleChange(event) {
|
|
11
|
+
if (disabled) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
const target = event.target;
|
|
15
|
+
checked = target.checked;
|
|
16
|
+
onChange();
|
|
17
|
+
}
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<label class="checkboxWrapper" class:disabled={disabled}>
|
|
21
|
+
<input type="checkbox" bind:checked on:change={handleChange} {disabled} aria-label={label} name={label} />
|
|
22
|
+
<span class="customCheckbox" style="--bg-color: var({color}); --check-mark-color: {checkMarkColor};">
|
|
23
|
+
{#if checked}
|
|
24
|
+
<svg
|
|
25
|
+
class="checkMark"
|
|
26
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
27
|
+
width="16"
|
|
28
|
+
height="16"
|
|
29
|
+
viewBox="0 0 24 24"
|
|
30
|
+
fill="none"
|
|
31
|
+
stroke="currentColor"
|
|
32
|
+
stroke-width="3"
|
|
33
|
+
stroke-linecap="round"
|
|
34
|
+
stroke-linejoin="round"
|
|
35
|
+
>
|
|
36
|
+
<polyline points="20 6 9 17 4 12" />
|
|
37
|
+
</svg>
|
|
38
|
+
{/if}
|
|
39
|
+
</span>
|
|
40
|
+
{#if label}
|
|
41
|
+
<span class="label">{label}</span>
|
|
42
|
+
{/if}
|
|
43
|
+
</label>
|
|
44
|
+
|
|
45
|
+
<style>
|
|
46
|
+
.checkboxWrapper {
|
|
47
|
+
display: flex;
|
|
48
|
+
align-items: center;
|
|
49
|
+
cursor: pointer;
|
|
50
|
+
position: relative;
|
|
51
|
+
}
|
|
52
|
+
.checkboxWrapper.disabled {
|
|
53
|
+
cursor: not-allowed;
|
|
54
|
+
opacity: 0.6;
|
|
55
|
+
}
|
|
56
|
+
.checkboxWrapper input[type='checkbox'] {
|
|
57
|
+
border: 0;
|
|
58
|
+
clip: rect(0 0 0 0);
|
|
59
|
+
clip-path: inset(50%);
|
|
60
|
+
height: 1px;
|
|
61
|
+
margin: -1px;
|
|
62
|
+
overflow: hidden;
|
|
63
|
+
padding: 0;
|
|
64
|
+
position: absolute;
|
|
65
|
+
white-space: nowrap;
|
|
66
|
+
width: 1px;
|
|
67
|
+
}
|
|
68
|
+
.customCheckbox {
|
|
69
|
+
width: 20px;
|
|
70
|
+
height: 20px;
|
|
71
|
+
border: 2px solid var(--bg-color);
|
|
72
|
+
border-radius: 4px;
|
|
73
|
+
display: flex;
|
|
74
|
+
justify-content: center;
|
|
75
|
+
align-items: center;
|
|
76
|
+
transition: background-color 0.2s;
|
|
77
|
+
}
|
|
78
|
+
.checkboxWrapper input[type='checkbox']:checked + .customCheckbox {
|
|
79
|
+
background-color: var(--bg-color);
|
|
80
|
+
}
|
|
81
|
+
.checkMark {
|
|
82
|
+
stroke: var(--check-mark-color);
|
|
83
|
+
}
|
|
84
|
+
.label {
|
|
85
|
+
margin-left: 8px;
|
|
86
|
+
font-size: 16px;
|
|
87
|
+
}
|
|
88
|
+
</style>
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
import './const/variables.css';
|
|
3
|
+
declare const __propDef: {
|
|
4
|
+
props: {
|
|
5
|
+
/**
|
|
6
|
+
* チェックボックスのラベル
|
|
7
|
+
* @default ''
|
|
8
|
+
* @type string
|
|
9
|
+
*/ label?: string;
|
|
10
|
+
/**
|
|
11
|
+
* チェックボックスの状態
|
|
12
|
+
* @default false
|
|
13
|
+
* @type boolean
|
|
14
|
+
*/ checked?: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* チェックボックスの色
|
|
17
|
+
* @default '--soda-blue'
|
|
18
|
+
* @type string
|
|
19
|
+
*/ color?: string;
|
|
20
|
+
/**
|
|
21
|
+
* 非活性状態
|
|
22
|
+
* @default false
|
|
23
|
+
* @type boolean
|
|
24
|
+
*/ disabled?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* 状態が変更されたときのイベントハンドラ
|
|
27
|
+
* @type {() => void}
|
|
28
|
+
*/ onChange?: () => void;
|
|
29
|
+
};
|
|
30
|
+
events: {
|
|
31
|
+
[evt: string]: CustomEvent<any>;
|
|
32
|
+
};
|
|
33
|
+
slots: {};
|
|
34
|
+
};
|
|
35
|
+
export type CheckboxProps = typeof __propDef.props;
|
|
36
|
+
export type CheckboxEvents = typeof __propDef.events;
|
|
37
|
+
export type CheckboxSlots = typeof __propDef.slots;
|
|
38
|
+
export default class Checkbox extends SvelteComponentTyped<CheckboxProps, CheckboxEvents, CheckboxSlots> {
|
|
39
|
+
}
|
|
40
|
+
export {};
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
<script>import { createEventDispatcher } from "svelte";
|
|
2
|
+
import { DateTime } from "luxon";
|
|
3
|
+
import "./const/variables.css";
|
|
4
|
+
const dispatch = createEventDispatcher();
|
|
5
|
+
export let selectedDate = null;
|
|
6
|
+
export let placeholder = "\u65E5\u4ED8\u3092\u9078\u629E";
|
|
7
|
+
export let id = "date-picker-" + Math.random().toString(36).substring(2, 9);
|
|
8
|
+
export let borderColor = "--strawberry-pink";
|
|
9
|
+
export let disableBlurClose = false;
|
|
10
|
+
let showCalendar = false;
|
|
11
|
+
let currentMonth = selectedDate ? DateTime.fromJSDate(selectedDate) : DateTime.local();
|
|
12
|
+
$: formattedDate = selectedDate ? DateTime.fromJSDate(selectedDate).toFormat("yyyy/MM/dd") : "";
|
|
13
|
+
function toggleCalendar() {
|
|
14
|
+
showCalendar = !showCalendar;
|
|
15
|
+
}
|
|
16
|
+
function selectDay(day) {
|
|
17
|
+
const newDate = currentMonth.set({ day }).toJSDate();
|
|
18
|
+
selectedDate = newDate;
|
|
19
|
+
dispatch("change", newDate);
|
|
20
|
+
showCalendar = false;
|
|
21
|
+
}
|
|
22
|
+
function prevMonth() {
|
|
23
|
+
currentMonth = currentMonth.minus({ months: 1 });
|
|
24
|
+
}
|
|
25
|
+
function nextMonth() {
|
|
26
|
+
currentMonth = currentMonth.plus({ months: 1 });
|
|
27
|
+
}
|
|
28
|
+
function getDaysInMonth(date) {
|
|
29
|
+
const startOfMonth = date.startOf("month");
|
|
30
|
+
const endOfMonth = date.endOf("month");
|
|
31
|
+
const days = [];
|
|
32
|
+
const startDayOfWeek = startOfMonth.weekday === 7 ? 0 : startOfMonth.weekday;
|
|
33
|
+
for (let i = 0; i < startDayOfWeek; i++) {
|
|
34
|
+
days.push(null);
|
|
35
|
+
}
|
|
36
|
+
for (let i = 1; i <= endOfMonth.day; i++) {
|
|
37
|
+
days.push(i);
|
|
38
|
+
}
|
|
39
|
+
const remainingDays = 42 - days.length;
|
|
40
|
+
for (let i = 0; i < remainingDays; i++) {
|
|
41
|
+
days.push(null);
|
|
42
|
+
}
|
|
43
|
+
return days;
|
|
44
|
+
}
|
|
45
|
+
$: daysInMonth = getDaysInMonth(currentMonth);
|
|
46
|
+
</script>
|
|
47
|
+
|
|
48
|
+
<div class="datePickerWrapper" style="--selected-color: var({borderColor});">
|
|
49
|
+
<input type="text" {id} value={formattedDate} placeholder={placeholder} on:focus={toggleCalendar} on:blur={() => { if (!disableBlurClose) toggleCalendar(); }} readonly style="border-color: var({borderColor});" />
|
|
50
|
+
|
|
51
|
+
{#if showCalendar}
|
|
52
|
+
<div class="calendarOverlay" on:mousedown|preventDefault={() => {}}>
|
|
53
|
+
<div class="calendarHeader">
|
|
54
|
+
<button on:click={prevMonth} aria-label="前月へ"><</button>
|
|
55
|
+
<span>{currentMonth.toFormat('yyyy年MM月')}</span>
|
|
56
|
+
<button on:click={nextMonth} aria-label="次月へ">></button>
|
|
57
|
+
</div>
|
|
58
|
+
<div class="weekdays">
|
|
59
|
+
<span>日</span>
|
|
60
|
+
<span>月</span>
|
|
61
|
+
<span>火</span>
|
|
62
|
+
<span>水</span>
|
|
63
|
+
<span>木</span>
|
|
64
|
+
<span>金</span>
|
|
65
|
+
<span>土</span>
|
|
66
|
+
</div>
|
|
67
|
+
<div class="daysGrid">
|
|
68
|
+
{#each daysInMonth as day}
|
|
69
|
+
<button
|
|
70
|
+
class:currentMonthDay={day !== null}
|
|
71
|
+
class:selected={selectedDate && day === DateTime.fromJSDate(selectedDate).day && currentMonth.month === DateTime.fromJSDate(selectedDate).month && currentMonth.year === DateTime.fromJSDate(selectedDate).year}
|
|
72
|
+
on:click={() => day && selectDay(day)}
|
|
73
|
+
disabled={day === null}
|
|
74
|
+
>
|
|
75
|
+
{day !== null ? day : ''}
|
|
76
|
+
</button>
|
|
77
|
+
{/each}
|
|
78
|
+
</div>
|
|
79
|
+
</div>
|
|
80
|
+
{/if}
|
|
81
|
+
</div>
|
|
82
|
+
|
|
83
|
+
<style>
|
|
84
|
+
.datePickerWrapper {
|
|
85
|
+
position: relative;
|
|
86
|
+
display: inline-block;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.datePickerWrapper input {
|
|
90
|
+
padding: 8px;
|
|
91
|
+
border: 1px solid #ccc;
|
|
92
|
+
border-radius: 4px;
|
|
93
|
+
width: 120px;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.calendarOverlay {
|
|
97
|
+
position: absolute;
|
|
98
|
+
background-color: white;
|
|
99
|
+
border: 1px solid #ccc;
|
|
100
|
+
border-radius: 4px;
|
|
101
|
+
padding: 10px;
|
|
102
|
+
z-index: 1000;
|
|
103
|
+
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
|
104
|
+
margin-top: 5px;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.calendarHeader {
|
|
108
|
+
display: flex;
|
|
109
|
+
justify-content: space-between;
|
|
110
|
+
align-items: center;
|
|
111
|
+
margin-bottom: 10px;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.calendarHeader button {
|
|
115
|
+
background: none;
|
|
116
|
+
border: none;
|
|
117
|
+
font-size: 1.2em;
|
|
118
|
+
cursor: pointer;
|
|
119
|
+
padding: 5px;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.weekdays,
|
|
123
|
+
.daysGrid {
|
|
124
|
+
display: grid;
|
|
125
|
+
grid-template-columns: repeat(7, 1fr);
|
|
126
|
+
text-align: center;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.weekdays span {
|
|
130
|
+
font-weight: bold;
|
|
131
|
+
padding: 5px 0;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.daysGrid button {
|
|
135
|
+
background: none;
|
|
136
|
+
border: none;
|
|
137
|
+
padding: 0;
|
|
138
|
+
width: 30px;
|
|
139
|
+
height: 30px;
|
|
140
|
+
line-height: 30px;
|
|
141
|
+
cursor: pointer;
|
|
142
|
+
border-radius: 4px;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.daysGrid button:hover:not([disabled]) {
|
|
146
|
+
background-color: #eee;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.daysGrid button.currentMonthDay {
|
|
150
|
+
color: #333;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.daysGrid button.selected {
|
|
154
|
+
background-color: var(--selected-color);
|
|
155
|
+
color: white;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.daysGrid button[disabled] {
|
|
159
|
+
color: #ccc;
|
|
160
|
+
cursor: default;
|
|
161
|
+
}
|
|
162
|
+
</style>
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
import './const/variables.css';
|
|
3
|
+
declare const __propDef: {
|
|
4
|
+
props: {
|
|
5
|
+
/**
|
|
6
|
+
* 選択された日付
|
|
7
|
+
* @default null
|
|
8
|
+
* @type {Date | null}
|
|
9
|
+
*/ selectedDate?: Date | null;
|
|
10
|
+
/**
|
|
11
|
+
* 日付ピッカーのプレースホルダーテキスト
|
|
12
|
+
* @default '日付を選択'
|
|
13
|
+
* @type string
|
|
14
|
+
*/ placeholder?: string;
|
|
15
|
+
/**
|
|
16
|
+
* 日付ピッカーのID
|
|
17
|
+
* @default ''
|
|
18
|
+
* @type string
|
|
19
|
+
*/ id?: string;
|
|
20
|
+
/**
|
|
21
|
+
* ボーダーカラー、CCLVividColorの中から選ぶ
|
|
22
|
+
* @default --strawberry-pink
|
|
23
|
+
* @type string
|
|
24
|
+
*/ borderColor?: string;
|
|
25
|
+
/**
|
|
26
|
+
* blurイベントでカレンダーを閉じないようにするか
|
|
27
|
+
* テスト用途で利用
|
|
28
|
+
* @default false
|
|
29
|
+
* @type boolean
|
|
30
|
+
*/ disableBlurClose?: boolean;
|
|
31
|
+
};
|
|
32
|
+
events: {
|
|
33
|
+
change: CustomEvent<any>;
|
|
34
|
+
} & {
|
|
35
|
+
[evt: string]: CustomEvent<any>;
|
|
36
|
+
};
|
|
37
|
+
slots: {};
|
|
38
|
+
};
|
|
39
|
+
export type DatePickerProps = typeof __propDef.props;
|
|
40
|
+
export type DatePickerEvents = typeof __propDef.events;
|
|
41
|
+
export type DatePickerSlots = typeof __propDef.slots;
|
|
42
|
+
export default class DatePicker extends SvelteComponentTyped<DatePickerProps, DatePickerEvents, DatePickerSlots> {
|
|
43
|
+
}
|
|
44
|
+
export {};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<script>export let label = "";
|
|
2
|
+
export let helpText = "";
|
|
3
|
+
export let errorMessage = "";
|
|
4
|
+
export let forId = "";
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<div class="formGroupWrapper">
|
|
8
|
+
{#if label}
|
|
9
|
+
<label for={forId} class="formLabel">{label}</label>
|
|
10
|
+
{/if}
|
|
11
|
+
|
|
12
|
+
<div class="formControl">
|
|
13
|
+
<slot />
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
{#if helpText && !errorMessage}
|
|
17
|
+
<p class="helpText">{helpText}</p>
|
|
18
|
+
{/if}
|
|
19
|
+
|
|
20
|
+
{#if errorMessage}
|
|
21
|
+
<p class="errorMessage">{errorMessage}</p>
|
|
22
|
+
{/if}
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
<style>
|
|
26
|
+
.formGroupWrapper {
|
|
27
|
+
margin-bottom: 16px;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.formLabel {
|
|
31
|
+
display: block;
|
|
32
|
+
font-size: 14px;
|
|
33
|
+
font-weight: bold;
|
|
34
|
+
margin-bottom: 4px;
|
|
35
|
+
color: #333;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.formControl {
|
|
39
|
+
/* スロットコンテンツのスタイルを調整するために必要に応じて追加 */
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.helpText {
|
|
43
|
+
font-size: 12px;
|
|
44
|
+
color: #666;
|
|
45
|
+
margin-top: 4px;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.errorMessage {
|
|
49
|
+
font-size: 12px;
|
|
50
|
+
color: #d9534f; /* Bootstrap danger color */
|
|
51
|
+
margin-top: 4px;
|
|
52
|
+
}
|
|
53
|
+
</style>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
declare const __propDef: {
|
|
3
|
+
props: {
|
|
4
|
+
/**
|
|
5
|
+
* フォーム要素のラベルテキスト
|
|
6
|
+
* @default ''
|
|
7
|
+
* @type string
|
|
8
|
+
*/ label?: string;
|
|
9
|
+
/**
|
|
10
|
+
* ユーザーへの補足説明やヒント
|
|
11
|
+
* @default ''
|
|
12
|
+
* @type string
|
|
13
|
+
*/ helpText?: string;
|
|
14
|
+
/**
|
|
15
|
+
* バリデーションエラーが発生した場合に表示するメッセージ
|
|
16
|
+
* @default ''
|
|
17
|
+
* @type string
|
|
18
|
+
*/ errorMessage?: string;
|
|
19
|
+
/**
|
|
20
|
+
* ラベルと入力要素を関連付けるためのID
|
|
21
|
+
* @default ''
|
|
22
|
+
* @type string
|
|
23
|
+
*/ forId?: string;
|
|
24
|
+
};
|
|
25
|
+
events: {
|
|
26
|
+
[evt: string]: CustomEvent<any>;
|
|
27
|
+
};
|
|
28
|
+
slots: {
|
|
29
|
+
default: {};
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
export type FormGroupProps = typeof __propDef.props;
|
|
33
|
+
export type FormGroupEvents = typeof __propDef.events;
|
|
34
|
+
export type FormGroupSlots = typeof __propDef.slots;
|
|
35
|
+
export default class FormGroup extends SvelteComponentTyped<FormGroupProps, FormGroupEvents, FormGroupSlots> {
|
|
36
|
+
}
|
|
37
|
+
export {};
|