@uniai-fe/uds-templates 0.5.10 → 0.5.12
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 +4 -0
- package/dist/styles.css +139 -79
- package/package.json +1 -1
- package/src/cctv/hooks/useRtcStream.ts +8 -1
- package/src/cctv/utils/video-state.ts +2 -0
- package/src/weather/index.scss +1 -0
- package/src/weather/styles/variables.scss +30 -0
- package/src/weather/styles/weather.scss +59 -51
- package/src/weather/types/index.ts +1 -0
- package/src/weather/types/provider.ts +34 -0
- package/src/weather/utils/locale.ts +39 -2
package/README.md
CHANGED
|
@@ -60,8 +60,12 @@ Next.js 서비스에서 primitives와 동일한 방식으로 **Raw TypeScript**
|
|
|
60
60
|
- `weatherCoordinate`
|
|
61
61
|
- `useWeatherKorea`
|
|
62
62
|
- `useOpenWeatherMap`
|
|
63
|
+
- `resolveWeatherProvider`
|
|
64
|
+
- `WEATHER_PROVIDER_CAPABILITIES`
|
|
63
65
|
- `WeatherPageHeaderContainerProps`
|
|
64
66
|
- `WeatherPageHeaderTexts`
|
|
67
|
+
- `WeatherProviderKey`
|
|
68
|
+
- `WeatherProviderCapability`
|
|
65
69
|
- `/service-inquiry`
|
|
66
70
|
- `ServiceInquiry.Form`
|
|
67
71
|
- `ServiceInquiry.OpenButton`
|
package/dist/styles.css
CHANGED
|
@@ -67,6 +67,30 @@
|
|
|
67
67
|
var(--spacing-padding-9, 32px) + env(safe-area-inset-top, 0px)
|
|
68
68
|
);
|
|
69
69
|
--auth-container-padding-bottom: var(--spacing-padding-10, 40px);
|
|
70
|
+
--weather-page-header-height: 2.4rem;
|
|
71
|
+
--weather-page-header-gap: var(--spacing-gap-6);
|
|
72
|
+
--weather-page-header-background: var(--color-surface-static-white);
|
|
73
|
+
--weather-icon-width: 2.5rem;
|
|
74
|
+
--weather-icon-height: 2.4rem;
|
|
75
|
+
--weather-address-icon-size: 1.6rem;
|
|
76
|
+
--weather-item-gap: var(--spacing-gap-4);
|
|
77
|
+
--weather-address-gap: var(--spacing-gap-2);
|
|
78
|
+
--weather-body-font-size: var(--font-body-xxsmall-size);
|
|
79
|
+
--weather-body-line-height: var(--font-body-xxsmall-line-height);
|
|
80
|
+
--weather-body-letter-spacing: var(--font-body-xxsmall-letter-spacing);
|
|
81
|
+
--weather-label-font-weight: 500;
|
|
82
|
+
--weather-label-value-gap: var(--spacing-gap-2);
|
|
83
|
+
--weather-value-font-weight: 600;
|
|
84
|
+
--weather-unit-font-size: 0.8385rem;
|
|
85
|
+
--weather-text-color: var(--color-label-standard);
|
|
86
|
+
--weather-label-color: var(--color-label-neutral);
|
|
87
|
+
--weather-alert-text-color: var(--color-primary-standard);
|
|
88
|
+
--weather-alert-background: var(--color-surface-static-blue);
|
|
89
|
+
--weather-alert-height: 2rem;
|
|
90
|
+
--weather-alert-padding-horizontal: var(--spacing-padding-3);
|
|
91
|
+
--weather-alert-radius: 0.6rem;
|
|
92
|
+
--weather-alert-font-size: var(--font-caption-medium-size);
|
|
93
|
+
--weather-alert-font-weight: 400;
|
|
70
94
|
/* Card layout */
|
|
71
95
|
--cctv-video-radius: 12px;
|
|
72
96
|
--cctv-list-gap: var(--spacing-gap-5);
|
|
@@ -1471,129 +1495,165 @@
|
|
|
1471
1495
|
letter-spacing: 0px;
|
|
1472
1496
|
}
|
|
1473
1497
|
|
|
1474
|
-
|
|
1475
|
-
|
|
1498
|
+
|
|
1499
|
+
|
|
1500
|
+
.weather-page-header {
|
|
1476
1501
|
display: flex;
|
|
1477
1502
|
align-items: center;
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1503
|
+
gap: var(--weather-page-header-gap);
|
|
1504
|
+
width: fit-content;
|
|
1505
|
+
height: var(--weather-page-header-height);
|
|
1506
|
+
background: var(--weather-page-header-background);
|
|
1507
|
+
white-space: nowrap;
|
|
1481
1508
|
}
|
|
1482
1509
|
|
|
1483
1510
|
.weather-base-icon {
|
|
1484
|
-
width: 2.5rem;
|
|
1485
|
-
height: 2.4rem;
|
|
1486
1511
|
position: relative;
|
|
1512
|
+
width: var(--weather-icon-width);
|
|
1513
|
+
height: var(--weather-icon-height);
|
|
1514
|
+
flex: 0 0 auto;
|
|
1487
1515
|
}
|
|
1488
1516
|
|
|
1489
|
-
.weather-
|
|
1517
|
+
.weather-address {
|
|
1490
1518
|
display: flex;
|
|
1491
1519
|
align-items: center;
|
|
1520
|
+
gap: var(--weather-address-gap);
|
|
1521
|
+
width: fit-content;
|
|
1492
1522
|
}
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
}
|
|
1497
|
-
.weather-base-text-info dt span, .weather-next-days-text dt span {
|
|
1498
|
-
color: var(--color-cool-gray-35);
|
|
1499
|
-
}
|
|
1500
|
-
.weather-base-text-info dd, .weather-next-days-text dd {
|
|
1501
|
-
font-size: 0;
|
|
1523
|
+
|
|
1524
|
+
.weather-address-icon {
|
|
1525
|
+
position: relative;
|
|
1502
1526
|
display: flex;
|
|
1503
|
-
align-items:
|
|
1527
|
+
align-items: center;
|
|
1528
|
+
justify-content: center;
|
|
1529
|
+
width: var(--weather-address-icon-size);
|
|
1530
|
+
height: var(--weather-address-icon-size);
|
|
1531
|
+
flex: 0 0 auto;
|
|
1504
1532
|
}
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1533
|
+
|
|
1534
|
+
.weather-address-text {
|
|
1535
|
+
display: flex;
|
|
1536
|
+
align-items: center;
|
|
1537
|
+
gap: var(--weather-address-gap);
|
|
1538
|
+
margin: 0;
|
|
1539
|
+
color: var(--weather-text-color);
|
|
1540
|
+
font-size: var(--weather-body-font-size);
|
|
1541
|
+
font-weight: var(--weather-label-font-weight);
|
|
1542
|
+
line-height: var(--weather-body-line-height);
|
|
1543
|
+
letter-spacing: var(--weather-body-letter-spacing);
|
|
1508
1544
|
}
|
|
1509
1545
|
|
|
1510
|
-
.weather-
|
|
1511
|
-
|
|
1512
|
-
height: 1.3rem;
|
|
1513
|
-
margin: 0 0.8rem;
|
|
1514
|
-
background: var(--color-cool-gray-85);
|
|
1546
|
+
.weather-address-date {
|
|
1547
|
+
color: var(--weather-label-color);
|
|
1515
1548
|
}
|
|
1516
1549
|
|
|
1517
|
-
.weather-
|
|
1550
|
+
.weather-today-container {
|
|
1518
1551
|
display: flex;
|
|
1519
1552
|
align-items: center;
|
|
1553
|
+
gap: var(--weather-item-gap);
|
|
1520
1554
|
width: fit-content;
|
|
1521
1555
|
}
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
}
|
|
1528
|
-
.weather-address-text {
|
|
1556
|
+
|
|
1557
|
+
.weather-today-text {
|
|
1558
|
+
display: flex;
|
|
1559
|
+
align-items: center;
|
|
1560
|
+
gap: var(--weather-item-gap);
|
|
1529
1561
|
width: fit-content;
|
|
1530
|
-
|
|
1562
|
+
}
|
|
1563
|
+
|
|
1564
|
+
.weather-next-days-container {
|
|
1531
1565
|
display: flex;
|
|
1532
1566
|
align-items: center;
|
|
1567
|
+
gap: var(--weather-item-gap);
|
|
1568
|
+
width: fit-content;
|
|
1533
1569
|
}
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1570
|
+
|
|
1571
|
+
.weather-temperature-text {
|
|
1572
|
+
margin: 0;
|
|
1573
|
+
color: var(--weather-text-color);
|
|
1574
|
+
font-size: 0;
|
|
1575
|
+
font-weight: var(--weather-label-font-weight);
|
|
1576
|
+
line-height: var(--weather-body-line-height);
|
|
1577
|
+
letter-spacing: var(--weather-body-letter-spacing);
|
|
1540
1578
|
}
|
|
1541
1579
|
|
|
1542
|
-
.weather-
|
|
1543
|
-
|
|
1580
|
+
.weather-humidity-text {
|
|
1581
|
+
margin: 0;
|
|
1582
|
+
color: var(--weather-text-color);
|
|
1583
|
+
font-size: 0;
|
|
1584
|
+
font-weight: var(--weather-label-font-weight);
|
|
1585
|
+
line-height: var(--weather-body-line-height);
|
|
1586
|
+
letter-spacing: var(--weather-body-letter-spacing);
|
|
1544
1587
|
}
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1588
|
+
|
|
1589
|
+
.weather-forecast-text {
|
|
1590
|
+
margin: 0;
|
|
1591
|
+
color: var(--weather-text-color);
|
|
1592
|
+
font-size: 0;
|
|
1593
|
+
font-weight: var(--weather-label-font-weight);
|
|
1594
|
+
line-height: var(--weather-body-line-height);
|
|
1595
|
+
letter-spacing: var(--weather-body-letter-spacing);
|
|
1548
1596
|
}
|
|
1549
1597
|
|
|
1550
|
-
.weather-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1598
|
+
.weather-label {
|
|
1599
|
+
color: var(--weather-label-color);
|
|
1600
|
+
font-size: var(--weather-body-font-size);
|
|
1601
|
+
font-weight: var(--weather-label-font-weight);
|
|
1602
|
+
margin-right: var(--weather-label-value-gap);
|
|
1554
1603
|
}
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1604
|
+
|
|
1605
|
+
.weather-value {
|
|
1606
|
+
color: var(--weather-text-color);
|
|
1607
|
+
font-size: var(--weather-body-font-size);
|
|
1608
|
+
font-weight: var(--weather-value-font-weight);
|
|
1559
1609
|
}
|
|
1560
|
-
|
|
1561
|
-
|
|
1610
|
+
|
|
1611
|
+
.weather-unit {
|
|
1612
|
+
color: var(--weather-text-color);
|
|
1613
|
+
font-size: var(--weather-unit-font-size);
|
|
1614
|
+
font-weight: var(--weather-value-font-weight);
|
|
1562
1615
|
}
|
|
1563
1616
|
|
|
1564
|
-
.weather-
|
|
1565
|
-
|
|
1617
|
+
.weather-range {
|
|
1618
|
+
color: var(--weather-text-color);
|
|
1619
|
+
font-size: var(--weather-body-font-size);
|
|
1620
|
+
font-weight: var(--weather-value-font-weight);
|
|
1566
1621
|
}
|
|
1567
1622
|
|
|
1568
1623
|
.weather-alert {
|
|
1624
|
+
display: flex;
|
|
1625
|
+
align-items: center;
|
|
1626
|
+
justify-content: center;
|
|
1569
1627
|
width: fit-content;
|
|
1570
|
-
height:
|
|
1571
|
-
padding: 0
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1628
|
+
height: var(--weather-alert-height);
|
|
1629
|
+
padding: 0 var(--weather-alert-padding-horizontal);
|
|
1630
|
+
border-radius: var(--weather-alert-radius);
|
|
1631
|
+
background-color: var(--weather-alert-background);
|
|
1632
|
+
box-sizing: border-box;
|
|
1633
|
+
}
|
|
1634
|
+
|
|
1635
|
+
.weather-alert-loading {
|
|
1575
1636
|
display: flex;
|
|
1576
1637
|
align-items: center;
|
|
1638
|
+
width: fit-content;
|
|
1639
|
+
height: var(--weather-page-header-height);
|
|
1577
1640
|
}
|
|
1641
|
+
|
|
1578
1642
|
.weather-alert-text {
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
font-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
line-height: 1.6;
|
|
1643
|
+
display: flex;
|
|
1644
|
+
align-items: center;
|
|
1645
|
+
color: var(--weather-alert-text-color);
|
|
1646
|
+
font-size: var(--weather-alert-font-size);
|
|
1647
|
+
font-weight: var(--weather-alert-font-weight);
|
|
1648
|
+
line-height: var(--weather-body-line-height);
|
|
1649
|
+
letter-spacing: var(--weather-body-letter-spacing);
|
|
1587
1650
|
}
|
|
1588
1651
|
|
|
1589
|
-
.weather-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
}
|
|
1595
|
-
.weather-next-days-text dd:nth-of-type(n + 2) .unit {
|
|
1596
|
-
font-size: 1rem;
|
|
1652
|
+
.weather-alert-text span {
|
|
1653
|
+
color: inherit;
|
|
1654
|
+
font-size: inherit;
|
|
1655
|
+
font-weight: inherit;
|
|
1656
|
+
line-height: inherit;
|
|
1597
1657
|
}
|
|
1598
1658
|
|
|
1599
1659
|
|
package/package.json
CHANGED
|
@@ -218,6 +218,7 @@ export function useCctvRtcStream({
|
|
|
218
218
|
useEffect(() => {
|
|
219
219
|
const camId = cam?.cam_id;
|
|
220
220
|
if (!camId) return;
|
|
221
|
+
|
|
221
222
|
const instanceKey = instanceKeyRef.current as string;
|
|
222
223
|
setLiveRegistry(prev => {
|
|
223
224
|
const next = { ...prev };
|
|
@@ -226,7 +227,13 @@ export function useCctvRtcStream({
|
|
|
226
227
|
next[camId] = perCam;
|
|
227
228
|
return next;
|
|
228
229
|
});
|
|
230
|
+
}, [cam?.cam_id, liveState, setLiveRegistry]);
|
|
231
|
+
|
|
232
|
+
useEffect(() => {
|
|
233
|
+
const camId = cam?.cam_id;
|
|
234
|
+
if (!camId) return;
|
|
229
235
|
|
|
236
|
+
const instanceKey = instanceKeyRef.current as string;
|
|
230
237
|
return () => {
|
|
231
238
|
setLiveRegistry(prev => {
|
|
232
239
|
const next = { ...prev };
|
|
@@ -240,7 +247,7 @@ export function useCctvRtcStream({
|
|
|
240
247
|
return next;
|
|
241
248
|
});
|
|
242
249
|
};
|
|
243
|
-
}, [cam?.cam_id,
|
|
250
|
+
}, [cam?.cam_id, setLiveRegistry]);
|
|
244
251
|
|
|
245
252
|
// 호출자에게 video ref와 상태값, 토큰 쿼리 상태를 전달한다.
|
|
246
253
|
return {
|
|
@@ -60,6 +60,7 @@ export function getOverlayMessage({
|
|
|
60
60
|
*/
|
|
61
61
|
export function getIsLive({
|
|
62
62
|
cam,
|
|
63
|
+
connectionState,
|
|
63
64
|
isTokenLoading,
|
|
64
65
|
isTokenError,
|
|
65
66
|
isStreaming,
|
|
@@ -70,6 +71,7 @@ export function getIsLive({
|
|
|
70
71
|
if (isTokenLoading || isTokenError) return false;
|
|
71
72
|
if (isStreaming) return false;
|
|
72
73
|
if (streamError) return false;
|
|
74
|
+
if (connectionState !== "connected") return false;
|
|
73
75
|
return true;
|
|
74
76
|
}
|
|
75
77
|
|
package/src/weather/index.scss
CHANGED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--weather-page-header-height: 2.4rem;
|
|
3
|
+
--weather-page-header-gap: var(--spacing-gap-6);
|
|
4
|
+
--weather-page-header-background: var(--color-surface-static-white);
|
|
5
|
+
|
|
6
|
+
--weather-icon-width: 2.5rem;
|
|
7
|
+
--weather-icon-height: 2.4rem;
|
|
8
|
+
--weather-address-icon-size: 1.6rem;
|
|
9
|
+
|
|
10
|
+
--weather-item-gap: var(--spacing-gap-4);
|
|
11
|
+
--weather-address-gap: var(--spacing-gap-2);
|
|
12
|
+
|
|
13
|
+
--weather-body-font-size: var(--font-body-xxsmall-size);
|
|
14
|
+
--weather-body-line-height: var(--font-body-xxsmall-line-height);
|
|
15
|
+
--weather-body-letter-spacing: var(--font-body-xxsmall-letter-spacing);
|
|
16
|
+
--weather-label-font-weight: 500;
|
|
17
|
+
--weather-label-value-gap: var(--spacing-gap-2);
|
|
18
|
+
--weather-value-font-weight: 600;
|
|
19
|
+
--weather-unit-font-size: 0.8385rem;
|
|
20
|
+
|
|
21
|
+
--weather-text-color: var(--color-label-standard);
|
|
22
|
+
--weather-label-color: var(--color-label-neutral);
|
|
23
|
+
--weather-alert-text-color: var(--color-primary-standard);
|
|
24
|
+
--weather-alert-background: var(--color-surface-static-blue);
|
|
25
|
+
--weather-alert-height: 2rem;
|
|
26
|
+
--weather-alert-padding-horizontal: var(--spacing-padding-3);
|
|
27
|
+
--weather-alert-radius: 0.6rem;
|
|
28
|
+
--weather-alert-font-size: var(--font-caption-medium-size);
|
|
29
|
+
--weather-alert-font-weight: 400;
|
|
30
|
+
}
|
|
@@ -1,117 +1,124 @@
|
|
|
1
1
|
.weather-page-header {
|
|
2
2
|
display: flex;
|
|
3
3
|
align-items: center;
|
|
4
|
-
gap:
|
|
4
|
+
gap: var(--weather-page-header-gap);
|
|
5
5
|
width: fit-content;
|
|
6
|
-
height:
|
|
6
|
+
height: var(--weather-page-header-height);
|
|
7
|
+
background: var(--weather-page-header-background);
|
|
7
8
|
white-space: nowrap;
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
.weather-base-icon {
|
|
11
12
|
position: relative;
|
|
12
|
-
width:
|
|
13
|
-
height:
|
|
13
|
+
width: var(--weather-icon-width);
|
|
14
|
+
height: var(--weather-icon-height);
|
|
14
15
|
flex: 0 0 auto;
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
.weather-address {
|
|
18
19
|
display: flex;
|
|
19
20
|
align-items: center;
|
|
20
|
-
gap:
|
|
21
|
+
gap: var(--weather-address-gap);
|
|
21
22
|
width: fit-content;
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
.weather-address-icon {
|
|
26
|
+
position: relative;
|
|
25
27
|
display: flex;
|
|
26
28
|
align-items: center;
|
|
27
29
|
justify-content: center;
|
|
28
|
-
width:
|
|
29
|
-
height:
|
|
30
|
+
width: var(--weather-address-icon-size);
|
|
31
|
+
height: var(--weather-address-icon-size);
|
|
30
32
|
flex: 0 0 auto;
|
|
31
33
|
}
|
|
32
34
|
|
|
33
35
|
.weather-address-text {
|
|
34
36
|
display: flex;
|
|
35
37
|
align-items: center;
|
|
36
|
-
gap:
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
font-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
gap: var(--weather-address-gap);
|
|
39
|
+
margin: 0;
|
|
40
|
+
color: var(--weather-text-color);
|
|
41
|
+
font-size: var(--weather-body-font-size);
|
|
42
|
+
font-weight: var(--weather-label-font-weight);
|
|
43
|
+
line-height: var(--weather-body-line-height);
|
|
44
|
+
letter-spacing: var(--weather-body-letter-spacing);
|
|
42
45
|
}
|
|
43
46
|
|
|
44
47
|
.weather-address-date {
|
|
45
|
-
color: var(--
|
|
48
|
+
color: var(--weather-label-color);
|
|
46
49
|
}
|
|
47
50
|
|
|
48
51
|
.weather-today-container {
|
|
49
52
|
display: flex;
|
|
50
53
|
align-items: center;
|
|
51
|
-
gap:
|
|
54
|
+
gap: var(--weather-item-gap);
|
|
52
55
|
width: fit-content;
|
|
53
56
|
}
|
|
54
57
|
|
|
55
58
|
.weather-today-text {
|
|
56
59
|
display: flex;
|
|
57
60
|
align-items: center;
|
|
58
|
-
gap:
|
|
61
|
+
gap: var(--weather-item-gap);
|
|
59
62
|
width: fit-content;
|
|
60
63
|
}
|
|
61
64
|
|
|
62
65
|
.weather-next-days-container {
|
|
63
66
|
display: flex;
|
|
64
67
|
align-items: center;
|
|
65
|
-
gap:
|
|
68
|
+
gap: var(--weather-item-gap);
|
|
66
69
|
width: fit-content;
|
|
67
70
|
}
|
|
68
71
|
|
|
69
72
|
.weather-temperature-text {
|
|
70
|
-
|
|
73
|
+
margin: 0;
|
|
74
|
+
color: var(--weather-text-color);
|
|
71
75
|
font-size: 0;
|
|
72
|
-
font-weight:
|
|
73
|
-
line-height:
|
|
74
|
-
letter-spacing:
|
|
76
|
+
font-weight: var(--weather-label-font-weight);
|
|
77
|
+
line-height: var(--weather-body-line-height);
|
|
78
|
+
letter-spacing: var(--weather-body-letter-spacing);
|
|
75
79
|
}
|
|
76
80
|
|
|
77
81
|
.weather-humidity-text {
|
|
78
|
-
|
|
82
|
+
margin: 0;
|
|
83
|
+
color: var(--weather-text-color);
|
|
79
84
|
font-size: 0;
|
|
80
|
-
font-weight:
|
|
81
|
-
line-height:
|
|
82
|
-
letter-spacing:
|
|
85
|
+
font-weight: var(--weather-label-font-weight);
|
|
86
|
+
line-height: var(--weather-body-line-height);
|
|
87
|
+
letter-spacing: var(--weather-body-letter-spacing);
|
|
83
88
|
}
|
|
84
89
|
|
|
85
90
|
.weather-forecast-text {
|
|
86
|
-
|
|
91
|
+
margin: 0;
|
|
92
|
+
color: var(--weather-text-color);
|
|
87
93
|
font-size: 0;
|
|
88
|
-
font-weight:
|
|
89
|
-
line-height:
|
|
90
|
-
letter-spacing:
|
|
94
|
+
font-weight: var(--weather-label-font-weight);
|
|
95
|
+
line-height: var(--weather-body-line-height);
|
|
96
|
+
letter-spacing: var(--weather-body-letter-spacing);
|
|
91
97
|
}
|
|
92
98
|
|
|
93
99
|
.weather-label {
|
|
94
|
-
color: var(--
|
|
95
|
-
font-size:
|
|
96
|
-
font-weight:
|
|
100
|
+
color: var(--weather-label-color);
|
|
101
|
+
font-size: var(--weather-body-font-size);
|
|
102
|
+
font-weight: var(--weather-label-font-weight);
|
|
103
|
+
margin-right: var(--weather-label-value-gap);
|
|
97
104
|
}
|
|
98
105
|
|
|
99
106
|
.weather-value {
|
|
100
|
-
color: var(--
|
|
101
|
-
font-size:
|
|
102
|
-
font-weight:
|
|
107
|
+
color: var(--weather-text-color);
|
|
108
|
+
font-size: var(--weather-body-font-size);
|
|
109
|
+
font-weight: var(--weather-value-font-weight);
|
|
103
110
|
}
|
|
104
111
|
|
|
105
112
|
.weather-unit {
|
|
106
|
-
color: var(--
|
|
107
|
-
font-size:
|
|
108
|
-
font-weight:
|
|
113
|
+
color: var(--weather-text-color);
|
|
114
|
+
font-size: var(--weather-unit-font-size);
|
|
115
|
+
font-weight: var(--weather-value-font-weight);
|
|
109
116
|
}
|
|
110
117
|
|
|
111
118
|
.weather-range {
|
|
112
|
-
color: var(--
|
|
113
|
-
font-size:
|
|
114
|
-
font-weight:
|
|
119
|
+
color: var(--weather-text-color);
|
|
120
|
+
font-size: var(--weather-body-font-size);
|
|
121
|
+
font-weight: var(--weather-value-font-weight);
|
|
115
122
|
}
|
|
116
123
|
|
|
117
124
|
.weather-alert {
|
|
@@ -119,27 +126,28 @@
|
|
|
119
126
|
align-items: center;
|
|
120
127
|
justify-content: center;
|
|
121
128
|
width: fit-content;
|
|
122
|
-
height:
|
|
123
|
-
padding: 0
|
|
124
|
-
border-radius:
|
|
125
|
-
background-color: var(--
|
|
129
|
+
height: var(--weather-alert-height);
|
|
130
|
+
padding: 0 var(--weather-alert-padding-horizontal);
|
|
131
|
+
border-radius: var(--weather-alert-radius);
|
|
132
|
+
background-color: var(--weather-alert-background);
|
|
133
|
+
box-sizing: border-box;
|
|
126
134
|
}
|
|
127
135
|
|
|
128
136
|
.weather-alert-loading {
|
|
129
137
|
display: flex;
|
|
130
138
|
align-items: center;
|
|
131
139
|
width: fit-content;
|
|
132
|
-
height:
|
|
140
|
+
height: var(--weather-page-header-height);
|
|
133
141
|
}
|
|
134
142
|
|
|
135
143
|
.weather-alert-text {
|
|
136
144
|
display: flex;
|
|
137
145
|
align-items: center;
|
|
138
|
-
color: var(--
|
|
139
|
-
font-size:
|
|
140
|
-
font-weight:
|
|
141
|
-
line-height:
|
|
142
|
-
letter-spacing:
|
|
146
|
+
color: var(--weather-alert-text-color);
|
|
147
|
+
font-size: var(--weather-alert-font-size);
|
|
148
|
+
font-weight: var(--weather-alert-font-weight);
|
|
149
|
+
line-height: var(--weather-body-line-height);
|
|
150
|
+
letter-spacing: var(--weather-body-letter-spacing);
|
|
143
151
|
}
|
|
144
152
|
|
|
145
153
|
.weather-alert-text span {
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Weather Provider; provider 식별자
|
|
3
|
+
* @desc 현재 확정된 provider만 나열하고, 국가별 상세 API 체계는 후속 결정에서 확장한다.
|
|
4
|
+
*/
|
|
5
|
+
export type WeatherProviderKey = "kma" | "openWeatherMap";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Weather Provider; provider별 지원 기능
|
|
9
|
+
* @property {boolean} now 현재 날씨 지원 여부
|
|
10
|
+
* @property {boolean} forecast 예보 날씨 지원 여부
|
|
11
|
+
* @property {boolean} alert 특보 지원 여부
|
|
12
|
+
*/
|
|
13
|
+
export interface WeatherProviderCapability {
|
|
14
|
+
/**
|
|
15
|
+
* 현재 날씨 지원 여부
|
|
16
|
+
*/
|
|
17
|
+
now: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* 예보 날씨 지원 여부
|
|
20
|
+
*/
|
|
21
|
+
forecast: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* 특보 지원 여부
|
|
24
|
+
*/
|
|
25
|
+
alert: boolean;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Weather Provider; provider capability registry
|
|
30
|
+
*/
|
|
31
|
+
export type WeatherProviderCapabilityRegistry = Record<
|
|
32
|
+
WeatherProviderKey,
|
|
33
|
+
WeatherProviderCapability
|
|
34
|
+
>;
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
WeatherPageHeaderTexts,
|
|
3
|
+
WeatherProviderCapabilityRegistry,
|
|
4
|
+
WeatherProviderKey,
|
|
5
|
+
} from "../types";
|
|
2
6
|
|
|
3
7
|
const WEATHER_PAGE_HEADER_DEFAULT_TEXTS: WeatherPageHeaderTexts = {
|
|
4
8
|
currentWeatherLoading: "현재 날씨 불러오는 중...",
|
|
@@ -25,6 +29,26 @@ const OPEN_WEATHER_MAP_LANG_BY_LOCALE: Record<string, string> = {
|
|
|
25
29
|
ja: "ja",
|
|
26
30
|
};
|
|
27
31
|
|
|
32
|
+
const WEATHER_DEFAULT_PROVIDER: WeatherProviderKey = "openWeatherMap";
|
|
33
|
+
|
|
34
|
+
const WEATHER_PROVIDER_BY_LOCALE_KEY: Record<string, WeatherProviderKey> = {
|
|
35
|
+
ko: "kma",
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const WEATHER_PROVIDER_CAPABILITIES: WeatherProviderCapabilityRegistry =
|
|
39
|
+
{
|
|
40
|
+
kma: {
|
|
41
|
+
now: true,
|
|
42
|
+
forecast: true,
|
|
43
|
+
alert: true,
|
|
44
|
+
},
|
|
45
|
+
openWeatherMap: {
|
|
46
|
+
now: true,
|
|
47
|
+
forecast: true,
|
|
48
|
+
alert: false,
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
|
|
28
52
|
/**
|
|
29
53
|
* Weather Locale; locale 기준 키 정규화
|
|
30
54
|
* @param {string} [locale] locale 코드
|
|
@@ -35,6 +59,19 @@ const OPEN_WEATHER_MAP_LANG_BY_LOCALE: Record<string, string> = {
|
|
|
35
59
|
export const getWeatherLocaleKey = (locale?: string): string =>
|
|
36
60
|
locale?.trim().toLowerCase().split(/[-_]/)[0] || "ko";
|
|
37
61
|
|
|
62
|
+
/**
|
|
63
|
+
* Weather Locale; locale 기준 provider 선택
|
|
64
|
+
* @param {string} [locale] locale 코드
|
|
65
|
+
* @return {WeatherProviderKey} 현재 locale에 사용할 weather provider
|
|
66
|
+
* @example
|
|
67
|
+
* resolveWeatherProvider("ko-KR")
|
|
68
|
+
*/
|
|
69
|
+
export const resolveWeatherProvider = (locale?: string): WeatherProviderKey => {
|
|
70
|
+
const localeKey = getWeatherLocaleKey(locale);
|
|
71
|
+
|
|
72
|
+
return WEATHER_PROVIDER_BY_LOCALE_KEY[localeKey] ?? WEATHER_DEFAULT_PROVIDER;
|
|
73
|
+
};
|
|
74
|
+
|
|
38
75
|
/**
|
|
39
76
|
* Weather Locale; KMA provider 사용 여부
|
|
40
77
|
* @param {string} [locale] locale 코드
|
|
@@ -43,7 +80,7 @@ export const getWeatherLocaleKey = (locale?: string): string =>
|
|
|
43
80
|
* isKoreaWeatherLocale("ko-KR")
|
|
44
81
|
*/
|
|
45
82
|
export const isKoreaWeatherLocale = (locale?: string): boolean =>
|
|
46
|
-
|
|
83
|
+
resolveWeatherProvider(locale) === "kma";
|
|
47
84
|
|
|
48
85
|
/**
|
|
49
86
|
* Weather Locale; page-header 텍스트 병합
|