@3birds/midori-ui 0.0.40 → 0.0.42

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
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M12 13H7V18H12V20H5V10H7V11H12V13M8 4V6H4V4H8M10 2H2V8H10V2M20 11V13H16V11H20M22 9H14V15H22V9M20 18V20H16V18H20M22 16H14V22H22V16Z" /></svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#18181B99" d="M12 13H7V18H12V20H5V10H7V11H12V13M8 4V6H4V4H8M10 2H2V8H10V2M20 11V13H16V11H20M22 9H14V15H22V9M20 18V20H16V18H20M22 16H14V22H22V16Z" /></svg>
@@ -0,0 +1,7 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
2
+ <title>star</title>
3
+ <path
4
+ fill="#FCB700"
5
+ d="M12,17.27L18.18,21L16.54,13.97L22,9.24L14.81,8.62L12,2L9.19,8.62L2,9.24L7.45,13.97L5.82,21L12,17.27Z"
6
+ />
7
+ </svg>
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import { alertSvg, checkCircleSvg, closeCircleSvg, informationSvg } from '..';
2
+ import { alertSvg, checkCircleSvg, closeCircleSvg, Img, informationSvg } from '..';
3
3
  import { alert } from '../alert';
4
4
 
5
5
  let popover: HTMLButtonElement | undefined = $state(undefined);
@@ -43,6 +43,6 @@
43
43
  class="alert rounded-3xl {color} fixed top-4 right-4 left-4 {$alert.show ? 'flex' : 'hidden'}"
44
44
  onclick={() => alert.close()}
45
45
  >
46
- <img src={icon} alt="アラート" class="size-6" />
46
+ <Img src={icon} alt="アラート" class="size-6" />
47
47
  {$alert.message}
48
48
  </button>
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import { fileTreeOutlineSvg, type BreadcrumbsItem } from '..';
2
+ import { fileTreeOutlineSvg, Img, type BreadcrumbsItem } from '..';
3
3
 
4
4
  let {
5
5
  items,
@@ -10,9 +10,9 @@
10
10
  } = $props();
11
11
  </script>
12
12
 
13
- <nav class="breadcrumbs p-0 text-sm {className}">
13
+ <nav class="breadcrumbs p-0 text-xs text-base-content/60 {className}">
14
14
  <ul class="flex-wrap items-center">
15
- <img src={fileTreeOutlineSvg} alt="パンくずリスト" class="mr-2 size-4" />
15
+ <Img src={fileTreeOutlineSvg} alt="パンくずリスト" class="mr-2 size-4" />
16
16
  {#each items as item}
17
17
  <li class={item.href ? 'shrink-0' : 'min-w-0'}>
18
18
  {#if item.href}
@@ -1,40 +1,25 @@
1
1
  <script lang="ts">
2
- import { calendarMonthGraySvg, noImageSvg, StarGraySvg } from '..';
2
+ import { calendarMonthGraySvg, Img } from '..';
3
3
  import type { ContentCasual } from '../types';
4
4
 
5
5
  let { content, searchParams = '' }: { content: ContentCasual; searchParams?: string } = $props();
6
-
7
- const onErrorImage = (e: Event): void => {
8
- const target = e.currentTarget as HTMLImageElement;
9
- target.src = noImageSvg;
10
- target.onerror = null;
11
- };
12
6
  </script>
13
7
 
14
8
  <a class="card w-full rounded-3xl card-sm" href="/contents/{content.id}{searchParams}">
15
9
  <figure class="aspect-3/2 rounded-3xl">
16
- <img
17
- src={content.thumbnail}
18
- alt={content.name}
19
- class="h-full w-full object-cover"
20
- onerror={onErrorImage}
21
- />
10
+ <Img src={content.thumbnail} alt={content.name} class="h-full w-full object-cover" />
22
11
  </figure>
23
12
  <div class="card-body gap-0.5 px-1 py-2">
24
13
  {#if content.schedules.length > 0}
25
14
  <p class="flex min-w-0 items-center gap-0.5 text-base-content/60">
26
- <img src={calendarMonthGraySvg} alt="スケジュール" class="size-3 shrink-0" />
15
+ <Img src={calendarMonthGraySvg} alt="スケジュール" class="size-3 shrink-0" />
27
16
  <span class="block min-w-0 truncate">{content.schedules.join(',')}</span>
28
17
  </p>
29
18
  {/if}
30
19
  <div class="flex">
31
- <h2 class="card-title min-w-0">
32
- <span class="block min-w-0 truncate">{content.name}</span>
20
+ <h2 class="card-title min-w-0 truncate">
21
+ {content.name}
33
22
  </h2>
34
- <p class="flex shrink-0 items-center justify-end gap-0.5 text-base-content/60">
35
- <img src={StarGraySvg} alt="評価" class="size-3 shrink-0" />
36
- {content.rate_average}
37
- </p>
38
23
  </div>
39
24
  {#if content.parents}
40
25
  <p class="flex items-center gap-1 text-base-content/60">
@@ -0,0 +1,17 @@
1
+ <script lang="ts">
2
+ import { Img, type ContentGeo } from '..';
3
+
4
+ let { content, searchParams = '' }: { content: ContentGeo; searchParams?: string } = $props();
5
+ </script>
6
+
7
+ <a
8
+ class="card fixed right-22 bottom-4 left-4 z-20 mx-auto card-side h-32 max-w-sm rounded-3xl bg-base-100 shadow-sm card-sm sm:right-4"
9
+ href="/contents/{content.id}{searchParams}"
10
+ >
11
+ <figure class="aspect-1">
12
+ <Img src={content.thumbnail} alt={content.name} class="h-full w-full object-cover" />
13
+ </figure>
14
+ <div class="card-body justify-center">
15
+ <h2 class="card-title">{content.name}</h2>
16
+ </div>
17
+ </a>
@@ -0,0 +1,8 @@
1
+ import { type ContentGeo } from '..';
2
+ type $$ComponentProps = {
3
+ content: ContentGeo;
4
+ searchParams?: string;
5
+ };
6
+ declare const CardSide: import("svelte").Component<$$ComponentProps, {}, "">;
7
+ type CardSide = ReturnType<typeof CardSide>;
8
+ export default CardSide;
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import { Btn, closeSvg, type FilterItem } from '..';
2
+ import { Btn, closeSvg, Img, type FilterItem } from '..';
3
3
 
4
4
  let {
5
5
  value = $bindable(),
@@ -16,7 +16,7 @@
16
16
  <p class="text-sm text-base-content/60">絞り込み:</p>
17
17
  {#each items as item}
18
18
  <input
19
- class="btn m-0.5 rounded-full btn-sm"
19
+ class="btn m-0.5 rounded-full bg-base-100 btn-outline btn-sm"
20
20
  type="checkbox"
21
21
  name="frameworks"
22
22
  aria-label={item.label}
@@ -24,7 +24,7 @@
24
24
  bind:group={value}
25
25
  />
26
26
  {/each}
27
- <Btn class="m-0.5 btn-circle btn-sm" type="reset">
28
- <img src={closeSvg} alt="クリア" class="size-4" />
27
+ <Btn class="m-0.5 btn-circle btn-outline btn-sm" type="reset">
28
+ <Img src={closeSvg} alt="クリア" class="size-4" />
29
29
  </Btn>
30
30
  </form>
@@ -0,0 +1,13 @@
1
+ <script lang="ts">
2
+ import { noImageSvg } from '..';
3
+
4
+ let { src, alt, class: className }: { src: string; alt: string; class?: string } = $props();
5
+
6
+ const onerror = (e: Event): void => {
7
+ const target = e.currentTarget as HTMLImageElement;
8
+ target.src = noImageSvg;
9
+ target.onerror = null;
10
+ };
11
+ </script>
12
+
13
+ <img {src} {alt} class={className} {onerror} />
@@ -0,0 +1,8 @@
1
+ type $$ComponentProps = {
2
+ src: string;
3
+ alt: string;
4
+ class?: string;
5
+ };
6
+ declare const Img: import("svelte").Component<$$ComponentProps, {}, "">;
7
+ type Img = ReturnType<typeof Img>;
8
+ export default Img;
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import type { InputType } from '..';
2
+ import { Img, type InputType } from '..';
3
3
 
4
4
  let {
5
5
  type,
@@ -44,7 +44,7 @@
44
44
  {/if}
45
45
  <label class="input w-full rounded-full {icon ? '' : 'px-5'}">
46
46
  {#if icon}
47
- <img src={icon} class="size-4" alt="アイコン" />
47
+ <Img src={icon} class="size-4" alt="アイコン" />
48
48
  {/if}
49
49
  <input
50
50
  {type}
@@ -1,4 +1,4 @@
1
- import type { InputType } from '..';
1
+ import { type InputType } from '..';
2
2
  type $$ComponentProps = {
3
3
  type: InputType;
4
4
  required?: boolean;
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import { Btn, closeSvg } from '..';
2
+ import { Btn, closeSvg, Img } from '..';
3
3
 
4
4
  let {
5
5
  value = $bindable(),
@@ -14,7 +14,7 @@
14
14
  <div class="modal-action">
15
15
  <form method="dialog">
16
16
  <Btn class="absolute top-2 right-2 btn-circle btn-ghost btn-sm" type="submit">
17
- <img src={closeSvg} alt="閉じる" class="size-6" />
17
+ <Img src={closeSvg} alt="閉じる" class="size-6" />
18
18
  </Btn>
19
19
  </form>
20
20
  </div>
@@ -1,4 +1,10 @@
1
1
  import type { PriorityChoice } from '../types';
2
+ export declare const MAP_ATTRIBUTION: string;
3
+ export declare const MAP_DEFAULT_ICON_SIZE: number[];
4
+ export declare const MAP_DEFAULT_ICON_ANCHOR: number[];
5
+ export declare const MAP_MAX_ZOOM: number;
6
+ export declare const MAP_DEFAULT_LATITUDE: number;
7
+ export declare const MAP_DEFAULT_LONGITUDE: number;
2
8
  export declare const PRIORITIES: PriorityChoice[];
3
9
  export declare const PRIORITIES_WITHOUT_LOG: PriorityChoice[];
4
10
  export declare const PREFECTURE_SVG: Record<string, string>;
@@ -1,3 +1,9 @@
1
+ export const MAP_ATTRIBUTION = '<a href="https://github.com/protomaps/basemaps">Protomaps</a> © <a href="https://openstreetmap.org">OpenStreetMap</a>';
2
+ export const MAP_DEFAULT_ICON_SIZE = [20, 20];
3
+ export const MAP_DEFAULT_ICON_ANCHOR = [10, 10];
4
+ export const MAP_MAX_ZOOM = 20;
5
+ export const MAP_DEFAULT_LATITUDE = 35.658;
6
+ export const MAP_DEFAULT_LONGITUDE = 139.745;
1
7
  export const PRIORITIES = [
2
8
  { label: 'フィールド', value: '50' },
3
9
  { label: 'イベント', value: '40' },
package/dist/index.d.ts CHANGED
@@ -7,8 +7,10 @@ export { default as Alert } from './components/Alert.svelte';
7
7
  export { default as Breadcrumbs } from './components/Breadcrumbs.svelte';
8
8
  export { default as Filter } from './components/Filter.svelte';
9
9
  export { default as Card } from './components/Card.svelte';
10
+ export { default as CardSide } from './components/CardSide.svelte';
10
11
  export { default as Header } from './components/Header.svelte';
11
12
  export { default as Pagination } from './components/Pagination.svelte';
13
+ export { default as Img } from './components/Img.svelte';
12
14
  export { default as accountSvg } from './assets/account.svg';
13
15
  export { default as alertSvg } from './assets/alert.svg';
14
16
  export { default as calendarMonthSvg } from './assets/calendar-month.svg';
@@ -48,6 +50,7 @@ export { default as refreshSvg } from './assets/refresh.svg';
48
50
  export { default as shapeOutlineSvg } from './assets/shape-outline.svg';
49
51
  export { default as StarSvg } from './assets/star.svg';
50
52
  export { default as StarGraySvg } from './assets/star-gray.svg';
53
+ export { default as StarYellowSvg } from './assets/star-yellow.svg';
51
54
  export { default as 北海道 } from './assets/prefs/北海道.svg';
52
55
  export { default as 青森県 } from './assets/prefs/青森県.svg';
53
56
  export { default as 岩手県 } from './assets/prefs/岩手県.svg';
@@ -244,5 +247,6 @@ export { authState } from './auth.svelte.ts';
244
247
  export * as firebase from './auth';
245
248
  export { auth } from './firebase';
246
249
  export * as modal from './modals-context.ts';
250
+ export * from './utils/index.ts';
247
251
  export { PRIORITIES, PRIORITIES_WITHOUT_LOG, PREFECTURE_SVG, POI_ICON } from './constants/index.ts';
248
- export type { BtnType, InputType, AlertType, AlertState, BreadcrumbsItem, FilterItem, Priority, PriorityChoice, ModalsContext, Data, ContentCasual, ContentGeo, Dashboard, DashboardPref } from './types/index.ts';
252
+ export type { BtnType, InputType, AlertType, AlertState, BreadcrumbsItem, FilterItem, Priority, PriorityChoice, ModalsContext, Data, ContentAdditionalInfo, ContentAdmin, ContentImage, ContentReview, ContentMinimal, ContentCasual, ContentFormal, ContentGeo, Dashboard, DashboardPref } from './types/index.ts';
package/dist/index.js CHANGED
@@ -8,8 +8,10 @@ export { default as Alert } from './components/Alert.svelte';
8
8
  export { default as Breadcrumbs } from './components/Breadcrumbs.svelte';
9
9
  export { default as Filter } from './components/Filter.svelte';
10
10
  export { default as Card } from './components/Card.svelte';
11
+ export { default as CardSide } from './components/CardSide.svelte';
11
12
  export { default as Header } from './components/Header.svelte';
12
13
  export { default as Pagination } from './components/Pagination.svelte';
14
+ export { default as Img } from './components/Img.svelte';
13
15
  export { default as accountSvg } from './assets/account.svg';
14
16
  export { default as alertSvg } from './assets/alert.svg';
15
17
  export { default as calendarMonthSvg } from './assets/calendar-month.svg';
@@ -49,6 +51,7 @@ export { default as refreshSvg } from './assets/refresh.svg';
49
51
  export { default as shapeOutlineSvg } from './assets/shape-outline.svg';
50
52
  export { default as StarSvg } from './assets/star.svg';
51
53
  export { default as StarGraySvg } from './assets/star-gray.svg';
54
+ export { default as StarYellowSvg } from './assets/star-yellow.svg';
52
55
  export { default as 北海道 } from './assets/prefs/北海道.svg';
53
56
  export { default as 青森県 } from './assets/prefs/青森県.svg';
54
57
  export { default as 岩手県 } from './assets/prefs/岩手県.svg';
@@ -245,4 +248,5 @@ export { authState } from "./auth.svelte.js";
245
248
  export * as firebase from './auth';
246
249
  export { auth } from './firebase';
247
250
  export * as modal from "./modals-context.js";
251
+ export * from "./utils/index.js";
248
252
  export { PRIORITIES, PRIORITIES_WITHOUT_LOG, PREFECTURE_SVG, POI_ICON } from "./constants/index.js";
@@ -31,6 +31,33 @@ export interface Data<T> {
31
31
  data?: T;
32
32
  message?: string;
33
33
  }
34
+ export interface ContentImage {
35
+ src: string;
36
+ credit: string;
37
+ link: string;
38
+ }
39
+ export interface ContentAdditionalInfo {
40
+ title: string;
41
+ body: string;
42
+ }
43
+ export interface ContentReview {
44
+ rating: number;
45
+ body: string;
46
+ photo?: string;
47
+ content_id: string;
48
+ content_name: string;
49
+ reviewer_nickname: string;
50
+ reviewer_icon?: string;
51
+ }
52
+ export interface ContentMinimal {
53
+ id: string;
54
+ name: string;
55
+ }
56
+ export interface ContentAdmin {
57
+ name: string;
58
+ midori: boolean;
59
+ photo?: string;
60
+ }
34
61
  export interface ContentCasual {
35
62
  id: string;
36
63
  name: string;
@@ -42,6 +69,34 @@ export interface ContentCasual {
42
69
  rate_average: number;
43
70
  schedules: string[];
44
71
  }
72
+ export interface ContentFormal {
73
+ id: string;
74
+ name: string;
75
+ latitude: number;
76
+ longitude: number;
77
+ map_zoom_level: number;
78
+ marker_color: string;
79
+ marker_icon: string;
80
+ address: string;
81
+ overview: string;
82
+ hp: string;
83
+ x: string;
84
+ instagram: string;
85
+ facebook: string;
86
+ images: ContentImage[];
87
+ parents: ContentMinimal[];
88
+ rate_average: number;
89
+ review_count: number;
90
+ schedules: string[];
91
+ fields: ContentCasual[];
92
+ events: ContentCasual[];
93
+ contents: ContentCasual[];
94
+ amenities: ContentCasual[];
95
+ logs: ContentCasual[];
96
+ additional_infos: ContentAdditionalInfo[];
97
+ reviews: ContentReview[];
98
+ admins: ContentAdmin[];
99
+ }
45
100
  export interface ContentGeo {
46
101
  latitude: number;
47
102
  longitude: number;
@@ -0,0 +1,7 @@
1
+ export declare const yen: (amount: number) => string;
2
+ export declare const withoutFormatText: (text?: string) => string;
3
+ export declare const autoFormatText: (text: string) => string;
4
+ export declare const date: (datetime: string) => string;
5
+ export declare const datetime: (datetime: string) => string;
6
+ export declare const datetimeForInput: (datetime: string) => string;
7
+ export declare const truncateWithEllipsis: (text: string, maxLength: number) => string;
@@ -0,0 +1,69 @@
1
+ export const yen = (amount) => `${amount.toLocaleString()}円`;
2
+ const processCustomMarkup = (text, type, replacer) => {
3
+ let pattern;
4
+ switch (type) {
5
+ case 'link':
6
+ pattern = /@link\[([^\]]*)\]\(([^\)]*)\)/g;
7
+ break;
8
+ case 'bold':
9
+ pattern = /@bold\[([^\]]*)\]/g;
10
+ break;
11
+ case 'small':
12
+ pattern = /@small\[([^\]]*)\]/g;
13
+ break;
14
+ }
15
+ return text.replace(pattern, (_, display, link) => replacer(display, link));
16
+ };
17
+ const stripCustomMarkup = (text, type) => {
18
+ return processCustomMarkup(text, type, (display) => display);
19
+ };
20
+ export const withoutFormatText = (text) => {
21
+ if (!text)
22
+ return '';
23
+ text = stripCustomMarkup(text, 'link');
24
+ text = stripCustomMarkup(text, 'bold');
25
+ text = stripCustomMarkup(text, 'small');
26
+ return text.replace(/\s+/g, '');
27
+ };
28
+ export const autoFormatText = (text) => {
29
+ text = escapeHtml(text);
30
+ text = processCustomMarkup(text, 'link', (display, link) => `<a href="${sanitizeUrl(link)}" target="_blank" rel="noopener noreferrer" class="link">${display}</a>`);
31
+ text = processCustomMarkup(text, 'bold', (display) => `<span class="font-bold">${display}</span>`);
32
+ text = processCustomMarkup(text, 'small', (display) => `<span class="text-xs">${display}</span>`);
33
+ return text;
34
+ };
35
+ export const date = (datetime) => {
36
+ return datetime.slice(0, 10).replace(/-/g, '/');
37
+ };
38
+ export const datetime = (datetime) => {
39
+ return datetime.slice(0, 16).replace(/-/g, '/').replace('T', ' ');
40
+ };
41
+ export const datetimeForInput = (datetime) => {
42
+ return datetime.slice(0, 16);
43
+ };
44
+ export const truncateWithEllipsis = (text, maxLength) => {
45
+ return text.length > maxLength ? `${text.slice(0, maxLength)}…` : text;
46
+ };
47
+ const escapeHtml = (text) => text
48
+ .replace(/&/g, '&amp;')
49
+ .replace(/</g, '&lt;')
50
+ .replace(/>/g, '&gt;')
51
+ .replace(/"/g, '&quot;')
52
+ .replace(/'/g, '&#39;');
53
+ const unescapeHtml = (text) => text
54
+ .replace(/&amp;/g, '&')
55
+ .replace(/&lt;/g, '<')
56
+ .replace(/&gt;/g, '>')
57
+ .replace(/&quot;/g, '"')
58
+ .replace(/&#39;/g, "'");
59
+ const sanitizeUrl = (url) => {
60
+ try {
61
+ const parsed = new URL(unescapeHtml(url));
62
+ if (parsed.protocol === 'http:' || parsed.protocol === 'https:')
63
+ return parsed.href;
64
+ }
65
+ catch {
66
+ // 不正なURL形式
67
+ }
68
+ return '#';
69
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@3birds/midori-ui",
3
- "version": "0.0.40",
3
+ "version": "0.0.42",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "dev": "vite dev",