@opendesign-plus-test/components 0.0.1-rc.2

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.
Files changed (52) hide show
  1. package/dist/components.cjs.js +1 -0
  2. package/dist/components.css +1 -0
  3. package/dist/components.es.js +1193 -0
  4. package/dist/components.umd.js +1 -0
  5. package/docs/design.md +27 -0
  6. package/docs/design_banner.md +41 -0
  7. package/docs/design_section.md +27 -0
  8. package/package.json +47 -0
  9. package/scripts/generate-components-index.js +81 -0
  10. package/src/assets/svg-icons/icon-chevron-right.svg +3 -0
  11. package/src/assets/svg-icons/icon-close.svg +3 -0
  12. package/src/assets/svg-icons/icon-delete.svg +3 -0
  13. package/src/assets/svg-icons/icon-header-back.svg +3 -0
  14. package/src/assets/svg-icons/icon-header-delete.svg +3 -0
  15. package/src/assets/svg-icons/icon-header-search.svg +4 -0
  16. package/src/assets/svg-icons/icon-moon.svg +3 -0
  17. package/src/assets/svg-icons/icon-sun.svg +3 -0
  18. package/src/components/OBanner.vue +390 -0
  19. package/src/components/OCookieNotice.vue +417 -0
  20. package/src/components/OCookieNoticeEl.vue +403 -0
  21. package/src/components/OHeaderSearch.vue +601 -0
  22. package/src/components/OPlusConfigProvider.vue +32 -0
  23. package/src/components/OSection.vue +178 -0
  24. package/src/components/OThemeSwitcher.vue +108 -0
  25. package/src/components/common/ClientOnlyWrapper.ts +21 -0
  26. package/src/components/common/ContentWrapper.vue +85 -0
  27. package/src/draft/Banner.vue +265 -0
  28. package/src/draft/ButtonCards.vue +106 -0
  29. package/src/draft/Feature.vue +134 -0
  30. package/src/draft/Footer.vue +512 -0
  31. package/src/draft/HorizontalAnchor.vue +165 -0
  32. package/src/draft/ItemSwiper.vue +133 -0
  33. package/src/draft/Logo.vue +141 -0
  34. package/src/draft/LogoCard.vue +75 -0
  35. package/src/draft/LogoV2.vue +19 -0
  36. package/src/draft/MainCard.vue +38 -0
  37. package/src/draft/MultiCard.vue +95 -0
  38. package/src/draft/MultiIconCard.vue +74 -0
  39. package/src/draft/OInfoCard.vue +176 -0
  40. package/src/draft/Process.vue +81 -0
  41. package/src/draft/Section.vue +167 -0
  42. package/src/draft/SingleTabCard.vue +85 -0
  43. package/src/draft/SliderCard.vue +110 -0
  44. package/src/env.d.ts +1 -0
  45. package/src/i18n/en.ts +20 -0
  46. package/src/i18n/index.ts +42 -0
  47. package/src/i18n/zh.ts +9 -0
  48. package/src/index.ts +34 -0
  49. package/src/shared/provide.ts +6 -0
  50. package/src/vue.d.ts +10 -0
  51. package/tsconfig.json +33 -0
  52. package/vite.config.ts +90 -0
@@ -0,0 +1,133 @@
1
+ <script setup lang="ts">
2
+ import { OFigure, OLink } from '@opensig/opendesign';
3
+ import type { PropType } from 'vue';
4
+
5
+ interface ItemLogoT {
6
+ logo: {
7
+ [key: string]: string;
8
+ };
9
+ href: string;
10
+ hrefEn: string;
11
+ }
12
+
13
+ defineProps({
14
+ // 轮播数据
15
+ data: {
16
+ type: Array as PropType<ItemLogoT[]>,
17
+ default: () => {
18
+ [];
19
+ },
20
+ },
21
+ // 反向轮播
22
+ reverseDirection: {
23
+ type: Boolean,
24
+ default: false,
25
+ },
26
+ // 语言
27
+ lang: {
28
+ type: String as PropType<'zh' | 'en'>,
29
+ default: 'zh',
30
+ },
31
+ // 风格
32
+ theme: {
33
+ type: String as PropType<'light' | 'dark'>,
34
+ default: 'light',
35
+ },
36
+ // 指定在何处显示链接的资源
37
+ target: {
38
+ type: String as PropType<'_blank' | '_parent' | '_self' | '_top'>,
39
+ default: '_blank',
40
+ },
41
+ });
42
+ </script>
43
+
44
+ <template>
45
+ <div v-if="data.length > 0" class="swiper">
46
+ <div class="swiper-list" :class="{ 'swiper-reverse': reverseDirection }">
47
+ <div v-for="(item, i) in data" :key="i" class="swiper-item">
48
+ <OLink v-if="item.href || item.hrefEn" :href="lang === 'en' ? item.hrefEn || item.href : item.href" :target="target">
49
+ <div class="swiper-card">
50
+ <OFigure :src="item.logo[theme]" />
51
+ </div>
52
+ </OLink>
53
+ <div v-else class="swiper-card">
54
+ <OFigure :src="item.logo[theme]" />
55
+ </div>
56
+ </div>
57
+ </div>
58
+ </div>
59
+ </template>
60
+
61
+ <style lang="scss" scoped>
62
+ .swiper {
63
+ display: flex;
64
+ white-space: nowrap;
65
+ overflow: hidden;
66
+ position: relative;
67
+ }
68
+ .swiper-list {
69
+ display: flex;
70
+ animation: marque 100s linear infinite;
71
+ @include respond-to('>phone') {
72
+ @include hover {
73
+ animation-play-state: paused;
74
+ }
75
+ }
76
+ }
77
+ .swiper-reverse {
78
+ animation: marquere 100s linear infinite;
79
+ }
80
+
81
+ .swiper-item {
82
+ display: flex;
83
+ }
84
+
85
+ .swiper-card {
86
+ width: 269px;
87
+ background-color: var(--o-color-fill2);
88
+ border-radius: var(--o-radius-xs);
89
+ margin-right: 24px;
90
+ display: inline-flex;
91
+ justify-content: center;
92
+ align-items: center;
93
+ overflow: hidden;
94
+ pointer-events: auto;
95
+ }
96
+ .o-figure {
97
+ width: 100%;
98
+ border-radius: var(--o-radius-xs);
99
+ :deep(img) {
100
+ width: 100%;
101
+ }
102
+ }
103
+
104
+ :deep(.o-link) {
105
+ .o-link-label {
106
+ display: flex;
107
+ }
108
+ }
109
+
110
+ @keyframes marque {
111
+ 0% {
112
+ transform: translateX(0%);
113
+ }
114
+ 100% {
115
+ transform: translateX(-50%);
116
+ }
117
+ }
118
+ @keyframes marquere {
119
+ 0% {
120
+ transform: translateX(-50%);
121
+ }
122
+ 100% {
123
+ transform: translateX(0);
124
+ }
125
+ }
126
+
127
+ @include respond-to('phone') {
128
+ .swiper-card {
129
+ width: 160px;
130
+ margin-right: 12px;
131
+ }
132
+ }
133
+ </style>
@@ -0,0 +1,141 @@
1
+ <script setup lang="ts">
2
+ import { computed, type PropType } from 'vue';
3
+ import { ORow, OCol, OLink, OFigure } from '@opensig/opendesign';
4
+
5
+ import ItemSwiper from '@component/ItemSwiper.vue';
6
+ import ContentWrapper from '@component/ContentWrapper.vue';
7
+
8
+ import { publisher } from '@/data/logo';
9
+
10
+ interface ItemLogoT {
11
+ logo: {
12
+ [key: string]: string;
13
+ };
14
+ href: string;
15
+ hrefEn: string;
16
+ }
17
+ interface ItemSwiperT {
18
+ children: ItemLogoT[];
19
+ reverseDirection: boolean;
20
+ }
21
+
22
+ defineProps({
23
+ // 语言
24
+ lang: {
25
+ type: String as PropType<'zh' | 'en'>,
26
+ default: 'zh',
27
+ },
28
+ // 风格
29
+ theme: {
30
+ type: String as PropType<'light' | 'dark'>,
31
+ default: 'light',
32
+ },
33
+ // 指定在何处显示链接的资源
34
+ target: {
35
+ type: String as PropType<'_blank' | '_parent' | '_self' | '_top'>,
36
+ default: '_blank',
37
+ },
38
+ });
39
+
40
+ const total = publisher.length;
41
+
42
+ const list = computed(() => {
43
+ const row = total > 15 ? 3 : 2;
44
+ const num = total / row;
45
+ let arr = [] as ItemSwiperT[];
46
+ for (let i = 0; i < row; i++) {
47
+ arr.push({
48
+ children: [...publisher.slice(i * num, (i + 1) * num).map(item => ({ ...item, hrefEn: item.hrefEn || '' })), ...publisher.slice(i * num, (i + 1) * num).map(item => ({ ...item, hrefEn: item.hrefEn || '' }))],
49
+ reverseDirection: false,
50
+ });
51
+ if (i === row - 1) {
52
+ arr[i].children = [...publisher.slice(i * num).map(item => ({ ...item, hrefEn: item.hrefEn || '' })), ...publisher.slice(i * num).map(item => ({ ...item, hrefEn: item.hrefEn || '' }))];
53
+ }
54
+ if (i % 2 === 1) {
55
+ arr[i].reverseDirection = true;
56
+ }
57
+ }
58
+ return arr;
59
+ });
60
+
61
+ const col = computed(() => {
62
+ let num = 5;
63
+ if (total < 6) {
64
+ num = total;
65
+ } else if (total < 7) {
66
+ num = 3;
67
+ } else if (total < 9) {
68
+ num = 4;
69
+ }
70
+ return num;
71
+ });
72
+ </script>
73
+
74
+ <template>
75
+ <div class="logo-swiper">
76
+ <template v-if="total > 10">
77
+ <ItemSwiper v-for="(item, index) in list" :key="index" :data="item.children"
78
+ :reverse-direction="item.reverseDirection" :lang="lang" :theme="theme" :target="target"
79
+ class="partner-swiper" />
80
+ </template>
81
+ <template v-else>
82
+ <ContentWrapper>
83
+ <ORow gap="24px 24px" wrap="wrap" class="logo-data">
84
+ <OCol v-for="item in publisher" :key="item.href" :flex="`0 0 ${100 / col}%`">
85
+ <div class="item-logo">
86
+ <OLink v-if="item.href || item.hrefEn" :href="lang === 'en' ? item.hrefEn || item.href : item.href"
87
+ :target="target">
88
+ <div class="logo-card">
89
+ <OFigure :src="item.logo[theme]" />
90
+ </div>
91
+ </OLink>
92
+ <div v-else class="logo-card">
93
+ <OFigure :src="item.logo[theme]" />
94
+ </div>
95
+ </div>
96
+ </OCol>
97
+ </ORow>
98
+ </ContentWrapper>
99
+ </template>
100
+ </div>
101
+ </template>
102
+
103
+ <style lang="scss" scoped>
104
+ .logo-swiper {
105
+ width: 100%;
106
+ overflow: hidden;
107
+ }
108
+
109
+ .partner-swiper {
110
+ &+.partner-swiper {
111
+ margin-top: 24px;
112
+
113
+ @include respond-to('laptop') {
114
+ margin-top: 20px;
115
+ }
116
+
117
+ @include respond-to('pad_h') {
118
+ margin-top: 16px;
119
+ }
120
+
121
+ @include respond-to('<=pad_v') {
122
+ margin-top: 12px;
123
+ }
124
+ }
125
+ }
126
+
127
+ .item-logo {
128
+ display: flex;
129
+ justify-content: center;
130
+ align-items: center;
131
+ background-color: var(--o-color-fill2);
132
+ border-radius: var(--o-radius-xs);
133
+
134
+ .o-figure {
135
+ :deep(img) {
136
+ width: auto;
137
+ max-height: 90px;
138
+ }
139
+ }
140
+ }
141
+ </style>
@@ -0,0 +1,75 @@
1
+ <script lang="ts" setup>
2
+ import { computed } from 'vue';
3
+ import { OCard, ORow, OCol, OFigure } from '@opensig/opendesign';
4
+ import { useScreen } from '@/composables/useScreen';
5
+
6
+ const { lePadV, isPhone } = useScreen();
7
+
8
+ interface CardT {
9
+ title: string;
10
+ content: string;
11
+ cover: string;
12
+ time: string;
13
+ }
14
+
15
+ defineProps({
16
+ cards: {
17
+ type: Array as () => CardT[],
18
+ default: () => [],
19
+ },
20
+ });
21
+
22
+ const columns = computed(() => {
23
+ if (isPhone.value) {
24
+ return '0 1 100%';
25
+ } else if (lePadV.value) {
26
+ return '0 1 50%';
27
+ }
28
+ return '0 1 33.3333%';
29
+ });
30
+
31
+ </script>
32
+
33
+ <template>
34
+ <div class="card-wrapper">
35
+ <ORow gap="var(--grid-column-gutter)">
36
+ <OCol v-for="(card, index) in cards" :key="index" :flex="columns">
37
+ <OCard :title="card.title" :detail="card.content" :cover-ratio="16 / 9" :layout="'v'">
38
+ <template #cover>
39
+ <div class="cover-box">
40
+ <OFigure :src="card.cover" alt="Card Cover" class="cover-image" />
41
+ </div>
42
+ </template>
43
+ <template #footer>
44
+ <div class="timestamp">
45
+ <span class="time">{{ card.time }}</span>
46
+ </div>
47
+ </template>
48
+ </OCard>
49
+ </OCol>
50
+ </ORow>
51
+ </div>
52
+ </template>
53
+
54
+ <style lang="scss" scoped>
55
+ .card-wrapper {
56
+ --grid-column-gutter: var(--o3-gap-6);
57
+ --card-detail-max-row: 2
58
+ }
59
+
60
+ .cover-box {
61
+ height: 100px;
62
+
63
+ :deep(.cover-image) {
64
+ height: 100%;
65
+ }
66
+
67
+ @include respond-to('<=pad_v') {
68
+ height: 72px;
69
+ }
70
+
71
+ @include respond-to('phone') {
72
+ height: 68px;
73
+ }
74
+ }
75
+ </style>
@@ -0,0 +1,19 @@
1
+ <script lang="ts" setup>
2
+ import {} from '@opensig/opendesign';
3
+
4
+ interface companyT {
5
+ href: string;
6
+ hrefEn: string;
7
+ logo: {
8
+ dark: string;
9
+ light: string;
10
+ };
11
+ }
12
+ defineProps<{
13
+ logos?: companyT[];
14
+ }>();
15
+ </script>
16
+ <template>
17
+ <div>logo</div>
18
+ </template>
19
+ <style lang="scss" scoped></style>
@@ -0,0 +1,38 @@
1
+ <script lang="ts" setup>
2
+ import type { PropType } from 'vue';
3
+ import type { LinkCardItemT } from './OInfoCard.vue';
4
+ import OInfoCard from './OInfoCard.vue';
5
+
6
+ defineProps({
7
+ cards: {
8
+ type: Array as PropType<LinkCardItemT[]>,
9
+ required: true,
10
+ },
11
+ });
12
+ </script>
13
+
14
+ <template>
15
+ <div class="card-list">
16
+ <OInfoCard v-for="(card, index) in cards" :key="index" :item="card" class="card-item"></OInfoCard>
17
+ </div>
18
+ </template>
19
+
20
+ <style lang="scss" scoped>
21
+ .card-list {
22
+ display: grid;
23
+ grid-template-columns: 3.95fr 6.05fr;
24
+ gap: var(--o3-gap-6);
25
+
26
+ .card-item {
27
+ &:first-child {
28
+ grid-row-start: 1;
29
+ grid-row-end: 3;
30
+
31
+ :deep(.o-card-main) {
32
+ display: flex;
33
+ justify-content: end;
34
+ }
35
+ }
36
+ }
37
+ }
38
+ </style>
@@ -0,0 +1,95 @@
1
+ <script lang="ts" setup>
2
+ import { computed } from 'vue';
3
+ import { OCard, OButton, OScroller } from '@opensig/opendesign';
4
+ import { useScreen } from '@/composables/useScreen';
5
+
6
+ const { lePadV } = useScreen();
7
+
8
+ interface CardT {
9
+ title: string;
10
+ content: string;
11
+ cover: string;
12
+ buttons?: { text: string; href?: string }[];
13
+ }
14
+
15
+ const props = defineProps({
16
+ cards: {
17
+ type: Array as () => CardT[],
18
+ default: () => [],
19
+ },
20
+ });
21
+
22
+ const cardCount = computed(() => props.cards.length);
23
+ const cardWidth = computed(() => {
24
+ if (lePadV.value) {
25
+ if (cardCount.value <= 2) {
26
+ return `calc((100% - var(--card-gap) * 1) / 2)`;
27
+ }
28
+ return `calc((100% - var(--card-gap) * 2) / 3)`;
29
+ } else {
30
+ if (cardCount.value <= 4) {
31
+ return `calc((100% - var(--card-gap) * ${cardCount.value - 1}) / ${cardCount.value})`;
32
+ }
33
+ return `calc((100% - var(--card-gap) * 3) / 4)`;
34
+ }
35
+
36
+ });
37
+ const coverRatio = computed(() => {
38
+ return cardCount.value === 2 ? 3 : 16 / 9;
39
+ });
40
+ </script>
41
+
42
+ <template>
43
+ <div class="multi-card-wrapper">
44
+ <OScroller class="pane" size="small" :show-type="lePadV ? 'never' : 'always'" disabled-y>
45
+ <template v-for="card in cards" :key="card.title">
46
+ <OCard :title="card.title" :detail="card.content" :cover="card.cover"
47
+ :cover-ratio="lePadV ? undefined : coverRatio" :layout="'v'" class="multi-card-item"
48
+ :style="{ width: cardWidth }">
49
+ <template #footer>
50
+ <div class="buttons">
51
+ <OButton v-for="(button, btnIndex) in card.buttons" :key="btnIndex" :href="button.href"
52
+ color="primary" round="pill" variant="outline" class="button">{{ button.text }}
53
+ </OButton>
54
+ </div>
55
+ </template>
56
+ </OCard>
57
+ </template>
58
+ </OScroller>
59
+ </div>
60
+ </template>
61
+
62
+ <style lang="scss" scoped>
63
+ .multi-card-wrapper {
64
+ width: 100%;
65
+ --card-gap: var(--o3-gap-5);
66
+ }
67
+
68
+ .pane {
69
+ white-space: nowrap;
70
+
71
+ :deep(.o-scrollbar) {
72
+ --scrollbar-x-bottom: calc(-1 * var(--o3-gap-5) - 4px)
73
+ }
74
+ }
75
+
76
+ .multi-card-item {
77
+ display: inline-flex;
78
+ margin-right: var(--card-gap);
79
+
80
+ &:last-child {
81
+ margin-right: 0;
82
+ }
83
+
84
+ @include respond-to('<=pad_v') {
85
+ :deep(.o-card-cover-img) {
86
+ height: 120px;
87
+ }
88
+ }
89
+ }
90
+
91
+ .buttons {
92
+ display: flex;
93
+ gap: 8px;
94
+ }
95
+ </style>
@@ -0,0 +1,74 @@
1
+ <script lang="ts" setup>
2
+ import { computed } from 'vue';
3
+ import { OCard, type CardPropsT } from '@opensig/opendesign';
4
+ import { useScreen } from '@/composables/useScreen.ts';
5
+
6
+ const { isPadV, isPhone } = useScreen();
7
+
8
+ export type IconCardT = Pick<CardPropsT, 'title' | 'detail' | 'icon'>;
9
+
10
+ const props = withDefaults(defineProps<{
11
+ /*卡片各自的配置*/
12
+ cards: IconCardT[];
13
+ /*布局*/
14
+ layout?: CardPropsT['layout'];
15
+ /*所有卡片的配置,优先级低于cards*/
16
+ cardProps?: Omit<CardPropsT, 'layout'>;
17
+ }>(), {
18
+ layout: 'v',
19
+ });
20
+
21
+ const gridTemplateColumns = computed(() => {
22
+ if (isPhone.value) {
23
+ return '1fr';
24
+ }
25
+ if (isPadV.value) {
26
+ switch (props.cards.length) {
27
+ case 1:
28
+ return '1fr';
29
+ default:
30
+ return '1fr 1fr';
31
+ }
32
+ }
33
+ switch (props.cards.length) {
34
+ case 1:
35
+ return '1fr';
36
+ case 2:
37
+ return '1fr 1fr';
38
+ default:
39
+ return '1fr 1fr 1fr';
40
+ }
41
+ });
42
+ </script>
43
+
44
+ <template>
45
+ <div v-if="props.cards?.length" class="multi-card-wrapper">
46
+ <OCard
47
+ v-for="(card, index) in cards"
48
+ :key="index"
49
+ class="multi-icon-card-item"
50
+ v-bind="{
51
+ ...props.cardProps,
52
+ layout: props.layout,
53
+ ...card
54
+ }"
55
+ />
56
+ </div>
57
+ </template>
58
+
59
+ <style lang="scss" scoped>
60
+ .multi-card-wrapper {
61
+ display: grid;
62
+ gap: var(--o3-gap-5) var(--o3-gap-6);
63
+ grid-template-columns: v-bind(gridTemplateColumns);
64
+ }
65
+ .o-card {
66
+ --card-content-color: var(--o-color-info3);
67
+ @include respond-to("phone") {
68
+ --card-header-text-size: 16px;
69
+ --card-header-text-height: 24px;
70
+ --card-content-text-size: 14px;
71
+ --card-content-text-height: 22px;
72
+ }
73
+ }
74
+ </style>