@salla.sa/twilight 1.0.4 → 1.0.6

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 (28) hide show
  1. package/components/package.json +2 -1
  2. package/components/src/_redirects +5 -0
  3. package/components/src/components/generate-summary.js +35 -0
  4. package/components/src/components/salla-login/readme.md +18 -0
  5. package/components/src/components/salla-login/salla-login.scss +105 -0
  6. package/components/src/components/salla-login/salla-login.tsx +110 -0
  7. package/components/src/components/search-modal/readme.md +17 -0
  8. package/components/src/components/search-modal/search-modal.scss +37 -0
  9. package/components/src/components/search-modal/search-modal.tsx +182 -0
  10. package/components/src/components/summary.json +1 -0
  11. package/components/src/components.d.ts +76 -0
  12. package/components/src/global/css/tailwind.min.css +1 -0
  13. package/components/src/global/variables.scss +90 -0
  14. package/components/src/index.html +66 -0
  15. package/components/src/index.ts +8 -0
  16. package/components/src/interfaces/colors.ts +1 -0
  17. package/components/src/interfaces/index.ts +2 -0
  18. package/components/src/interfaces/ratio.ts +1 -0
  19. package/components/src/plugins/tailwind-theme/index.js +32 -0
  20. package/components/src/plugins/tailwind-theme/package.json +28 -0
  21. package/components/src/plugins/tailwind-theme/readme.md +47 -0
  22. package/components/src/plugins/tailwind-theme/safe-list-css.txt +19 -0
  23. package/components/src/plugins/tailwind-theme/utilities.json +1 -0
  24. package/components/src/tsconfig.app.json +8 -0
  25. package/components/src/utils/utils.spec.ts +21 -0
  26. package/components/src/utils/utils.ts +20 -0
  27. package/package.json +2 -1
  28. package/twilight/postInstall.js +2 -0
@@ -19,7 +19,8 @@
19
19
  "unpkg": "dist/atoms/atoms.js",
20
20
  "files": [
21
21
  "dist/",
22
- "loader/"
22
+ "loader/",
23
+ "src/"
23
24
  ],
24
25
  "repository": {
25
26
  "type": "git",
@@ -0,0 +1,5 @@
1
+ # *** Warning! Your custom domain is not using HTTPS yet ***
2
+ # These rules will change if you change your site’s custom domains or HTTPS settings
3
+
4
+ # Redirect default Netlify subdomain to primary domain
5
+ https://salla-web-components.netlify.com/* https://salla-web-components.salla.sa/:splat 301!
@@ -0,0 +1,35 @@
1
+ var fs = require('fs'), path = require('path'), util = require('util');
2
+
3
+ var dirToJSON = function (dir, done) {
4
+ var results = [];
5
+
6
+ function recWalk(d, res) {
7
+ var list = fs.readdirSync(d);
8
+ list.forEach((name) => {
9
+ var file = path.resolve(d, name);
10
+ var stat = fs.statSync(file);
11
+ if (stat && stat.isDirectory()) {
12
+ var title;
13
+ if (name) {
14
+ title = 'salla-' + name
15
+ }
16
+ res.push({ title: title, file: name + '/readme.md' });
17
+ }
18
+ });
19
+ }
20
+
21
+ try {
22
+ recWalk(dir, results);
23
+ done(null, results);
24
+ } catch (err) {
25
+ done(err);
26
+ }
27
+ };
28
+
29
+ dirToJSON("src/components", function (err, results) {
30
+ if (err) console.log(err);
31
+ else fs.writeFile('src/components/summary.json', JSON.stringify(results), 'utf8', function (err) {
32
+ if (err) throw err;
33
+ console.log('Saved!');
34
+ });
35
+ });
@@ -0,0 +1,18 @@
1
+ # salla-login
2
+
3
+
4
+
5
+ <!-- Auto Generated Below -->
6
+
7
+
8
+ ## Properties
9
+
10
+ | Property | Attribute | Description | Type | Default |
11
+ | ------------ | ------------- | -------------------------------------- | --------- | ------------------- |
12
+ | `searchIcon` | `search-icon` | | `string` | `'Search_Icon.svg'` |
13
+ | `visible` | `visible` | If 'true' will make the modal visible. | `boolean` | `false` |
14
+
15
+
16
+ ----------------------------------------------
17
+
18
+ *Built with [StencilJS](https://stenciljs.com/)*
@@ -0,0 +1,105 @@
1
+ .wrapper {
2
+ opacity: 0;
3
+ visibility: hidden;
4
+ position: fixed;
5
+ width: 100%;
6
+ height: 100%;
7
+ top: 0;
8
+ left: 0;
9
+
10
+ background: rgb(252 252 252);
11
+ -webkit-transition: opacity 0.5s, visibility 0s 0.5s;
12
+ transition: opacity 0.5s, visibility 0s 0.5s;
13
+
14
+ display: flex;
15
+ align-items: center;
16
+ justify-content: center;
17
+ z-index: 1050;
18
+
19
+ .modal {
20
+ font-family: Helvetica, sans-serif;
21
+ font-size: 14px;
22
+ background-color: #fff;
23
+ position: absolute;
24
+ top: 50%;
25
+ left: 50%;
26
+ transform: translate(-50%, -50%);
27
+ width: 90%;
28
+
29
+ @media (min-width: 576px) {
30
+ max-width: 500px;
31
+ }
32
+
33
+ border: 1px solid rgba(0, 0, 0, 0.2);
34
+ border-radius: 0.3rem;
35
+
36
+ .displayed {
37
+ display: flex;
38
+ }
39
+
40
+ .modal-body {
41
+ position: relative;
42
+ -ms-flex: 1 1 auto;
43
+ flex: 1 1 auto;
44
+ padding: 1rem;
45
+ }
46
+ }
47
+ }
48
+
49
+ .visible {
50
+ opacity: 1;
51
+ visibility: visible;
52
+ transform: scale(1);
53
+ transition: visibility 0s linear 0s, opacity 0.25s 0s, transform 0.25s;
54
+ }
55
+
56
+ .hide {
57
+ display: none !important;
58
+ }
59
+
60
+ .show {
61
+ display: block !important;
62
+ }
63
+
64
+ .search-box {
65
+ display: flex;
66
+
67
+ input {
68
+ width: 100%;
69
+ padding: 10px;
70
+ padding-inline-start: 32px;
71
+ }
72
+ button{
73
+ background-color: transparent;
74
+ border: 0;
75
+ position: absolute;
76
+ padding: 12px;
77
+ left: 12px;
78
+ }
79
+ }
80
+
81
+ .results {
82
+ list-style: none;
83
+ padding: 0;
84
+ margin: 0;
85
+ max-height: 300px;
86
+ overflow-y: scroll;
87
+
88
+ .product-img {
89
+ width: 50px;
90
+ margin-inline-end: 10px;
91
+ }
92
+
93
+ a:first-child{
94
+ margin-top: 20px;
95
+ }
96
+
97
+ a {
98
+ display: flex;
99
+ border-bottom: 1px solid #ddd;
100
+
101
+ h5 {
102
+ margin-top: 5px;
103
+ }
104
+ }
105
+ }
@@ -0,0 +1,110 @@
1
+ import { Component, h, Prop, Listen, State } from '@stencil/core';
2
+
3
+ @Component({
4
+ tag: 'salla-login',
5
+ styleUrl: 'salla-login.scss',
6
+ shadow: true,
7
+ assetsDirs: ['assets'],
8
+ })
9
+ export class SallaLogin {
10
+ @State() searchTerm: string;
11
+ @State() results: string[];
12
+ @State() fetchStatus: string = '';
13
+ @State() showResult: boolean;
14
+ @Prop() searchIcon = 'Search_Icon.svg';
15
+
16
+ /**
17
+ * If 'true' will make the modal visible.
18
+ */
19
+ @Prop({ mutable: true, reflect: true }) visible: boolean = false;
20
+
21
+ @Listen('click', { target: 'window' })
22
+ handleClick(ev) {
23
+ if (
24
+ !ev.path.some(x => x.className && x.className.includes('modal-body')) &&
25
+ ev.target.localName === 'salla-search-modal'
26
+ ) {
27
+ this.visible = false;
28
+ }
29
+ }
30
+
31
+
32
+ private handleClose = () => {
33
+ this.visible = false;
34
+ };
35
+
36
+
37
+ render() {
38
+ return (
39
+ <div class={this.visible ? 'wrapper visible' : 'wrapper'}>
40
+ <div class="modal">
41
+
42
+ <div class='modal-header'>
43
+ <h5 class="title">سجل دخول إلي الموقع</h5>
44
+ <button
45
+ type="button"
46
+ class="close"
47
+ data-dismiss="modal"
48
+ aria-label="Close"
49
+ onClick={this.handleClose}
50
+ >
51
+ <span aria-hidden="true">×</span>
52
+ </button>
53
+ </div>
54
+ <div class="modal-body">
55
+
56
+ <div id="showLoginMethods">
57
+ <p class="text-sm text-gray-text mb-5">اختر الوسيلة المناسبة</p>
58
+ <div id="openEmailLogin" class="mb-2.5 box-content relative rounded-md border border-border-color bg-white py-5 pe-4 ps-5 flex items-center space-s-3 hover:border-gray-200">
59
+ <div class="flex-shrink-0">
60
+ <div class="bg-primary w-12 h-12 text-lg text-white rounded-icon">
61
+ <i class="sicon-mail"></i>
62
+ </div>
63
+ </div>
64
+ <div class="flex-1 min-w-0">
65
+ <a href="#" class="focus:outline-none flex justify-between items-center">
66
+ <div class="flex-1">
67
+ <span class="absolute inset-0" aria-hidden="true"></span>
68
+ <p class="text-sm text-gray-text">
69
+ سجل دخول
70
+ </p>
71
+ <h6 class="font-boldf">
72
+ البريد الإلكتروني
73
+ </h6>
74
+ </div>
75
+ <i class="sicon-keyboard_arrow_left text-primary text-xl"></i>
76
+ </a>
77
+ </div>
78
+ </div>
79
+ <div class="box-content relative rounded-md border border-border-color bg-white py-5 pe-4 ps-5 flex items-center space-s-3 hover:border-gray-200">
80
+ <div class="flex-shrink-0">
81
+ <div class="bg-primary w-12 h-12 text-lg text-white rounded-icon">
82
+ <i class="sicon-phone"></i>
83
+ </div>
84
+ </div>
85
+ <div class="flex-1 min-w-0">
86
+ <a href="#" class="focus:outline-none flex justify-between items-center">
87
+ <div class="flex-1">
88
+ <span class="absolute inset-0" aria-hidden="true"></span>
89
+ <p class="text-sm text-gray-text">
90
+ سجل دخول
91
+ </p>
92
+ <h6 class="font-boldf">
93
+ الهاتف
94
+ </h6>
95
+ </div>
96
+ <i class="sicon-keyboard_arrow_left text-primary text-xl"></i>
97
+ </a>
98
+ </div>
99
+ </div>
100
+ </div>
101
+
102
+
103
+
104
+
105
+ </div>
106
+ </div>
107
+ </div>
108
+ );
109
+ }
110
+ }
@@ -0,0 +1,17 @@
1
+ # salla-search-modal
2
+
3
+
4
+
5
+ <!-- Auto Generated Below -->
6
+
7
+
8
+ ## Properties
9
+
10
+ | Property | Attribute | Description | Type | Default |
11
+ | ------------------- | -------------------- | ----------------------------------------- | -------- | ------------------- |
12
+ | `searchPlaceholder` | `search-placeholder` | The text to overwrite search placeholder. | `string` | `'Search here ...'` |
13
+
14
+
15
+ ----------------------------------------------
16
+
17
+ *Built with [StencilJS](https://stenciljs.com/)*
@@ -0,0 +1,37 @@
1
+ // .s-search-modal-search-button-icon {}
2
+
3
+ // .s-search-modal-container {}
4
+
5
+ // .s-search-modal-wrapper {}
6
+
7
+ // .s-search-modal-inner {}
8
+
9
+ // .s-search-modal-search-box-container {}
10
+
11
+ // .s-search-modal-search-box-inner {}
12
+
13
+ // .s-search-modal-search-box-inner-open {}
14
+
15
+ // .s-search-modal-input {}
16
+
17
+ // .s-search-modal-search-icon {}
18
+
19
+ // .s-search-modal-spinner {}
20
+
21
+ // .s-search-modal-spinner-loader {}
22
+
23
+ // .s-search-modal-search-results {}
24
+
25
+ // .s-search-modal-no-results {}
26
+
27
+ // .s-search-modal-product {}
28
+
29
+ // .s-search-modal-product-image-container {}
30
+
31
+ // .s-search-modal-product-image {}
32
+
33
+ // .s-search-modal-product-details {}
34
+
35
+ // .s-search-modal-product-title {}
36
+
37
+ // .s-search-modal-product-price {}
@@ -0,0 +1,182 @@
1
+ import { Component, h, Host, Prop, State, Element } from '@stencil/core';
2
+ import { HTMLStencilElement } from '@stencil/core/internal';
3
+
4
+ @Component({
5
+ tag: 'salla-search-modal',
6
+ styleUrl: 'search-modal.scss',
7
+ scoped: false,
8
+ assetsDirs: ['assets'],
9
+ })
10
+ export class SearchModal {
11
+ @State() searchTerm: string;
12
+ @State() results: string[];
13
+ @State() fetchStatus: string = '';
14
+ @State() showResult: boolean;
15
+ @State() showModal: boolean = false;
16
+
17
+ /**
18
+ * The text to overwrite search placeholder.
19
+ */
20
+ @Prop() searchPlaceholder: string = 'Search here ...';
21
+
22
+ /**
23
+ * The text to overwrite no results text.
24
+ */
25
+ @Prop() noResultsText: string = 'There are no results at the moment';
26
+
27
+ private hasSearchIconSlot: boolean;
28
+ private hasProductTemplateSlot: boolean;
29
+ private productTemplateHtml: string;
30
+
31
+
32
+ @Element() hostElement: HTMLStencilElement;
33
+ componentWillLoad() {
34
+ this.hasSearchIconSlot = !!this.hostElement.querySelector('[slot="search-icon"]');
35
+ this.hasProductTemplateSlot = !!this.hostElement.querySelector('[slot="product-template"]');
36
+ if(this.hasProductTemplateSlot){
37
+ this.productTemplateHtml = this.hostElement.querySelector('[slot="product-template"]').innerHTML;
38
+ }
39
+
40
+ }
41
+
42
+ private handleChange = event => {
43
+ this.searchTerm = event.target.value;
44
+ this.fetchStatus = 'loading';
45
+ this.showResult = false;
46
+ this.results = [];
47
+ if (this.searchTerm.length > 2) {
48
+ window.salla.search.api
49
+ .search(this.searchTerm)
50
+ .then(response => response)
51
+ .then(response => {
52
+ console.log('response', response);
53
+ this.fetchStatus = 'idle';
54
+ this.results = response.results;
55
+ this.showResult = true;
56
+ if (this.results.length < 1) {
57
+ this.fetchStatus = 'error';
58
+ }
59
+ })
60
+ .catch(err => {
61
+ this.showResult = true;
62
+ this.fetchStatus = 'error';
63
+ console.log(err);
64
+ });
65
+ }
66
+ };
67
+
68
+ private getProduct(item) {
69
+ // todo use art-template https://aui.github.io/art-template/docs/.
70
+ if(this.hasProductTemplateSlot) {
71
+ let product = this.productTemplateHtml
72
+ .replace("{title}", item.title)
73
+ .replace("{price}", item.price?.after)
74
+ .replace("{url}", item.url)
75
+ .replace("{thumb}", item.thumb);
76
+ return (
77
+ <div class="s-search-modal-product" innerHTML={product}></div>
78
+ )
79
+ }else{
80
+ return (
81
+ <div class="s-search-modal-product">
82
+ <a target="_blank" href={item.url} class="s-search-modal-product-image-container">
83
+ <img class="s-search-modal-product-image" src={item.thumb} />
84
+ </a>
85
+ <div class="s-search-modal-product-details">
86
+ <div class="s-search-modal-product-title">
87
+ {item.title}
88
+ </div>
89
+ <div class="s-search-modal-product-price">
90
+ {item.price?.after}
91
+ </div>
92
+ </div>
93
+ </div>
94
+ );
95
+ }
96
+ }
97
+
98
+ private openSearch = () => {
99
+ this.searchTerm = '';
100
+ this.fetchStatus = '';
101
+ this.results = [];
102
+ this.showModal = true;
103
+ window.scrollTo(0, 0);
104
+ document.getElementsByTagName('html')[0].style.position = 'fixed';
105
+ document.getElementsByTagName('html')[0].style.overflowY = 'scroll';
106
+ };
107
+
108
+ private closeSearch = () => {
109
+ this.searchTerm = '';
110
+ this.fetchStatus = '';
111
+ this.results = [];
112
+ document.getElementsByTagName('html')[0].style.position = 'static';
113
+ document.getElementsByTagName('html')[0].style.overflowY = 'auto';
114
+ this.showModal = false;
115
+ };
116
+
117
+ render() {
118
+ return (
119
+ <Host class="s-search-modal">
120
+ <button type="button" onClick={this.openSearch} class="s-search-modal-search-button-icon">
121
+ {this.hasSearchIconSlot ? (
122
+ <slot name="search-icon" />
123
+ ) : (
124
+ <i class="sicon-search font-bold"></i>
125
+ )}
126
+ </button>
127
+
128
+ {this.showModal && (
129
+ <div class="s-search-modal-container" style={{ backgroundColor: 'rgba(0,0,0,0.5)' }}>
130
+ <div class="s-search-modal-wrapper" onClick={this.closeSearch}>
131
+ <div class="s-search-modal-inner" onClick={e => {
132
+ e.stopPropagation();
133
+ }}>
134
+ <div class="s-search-modal-search-box-container">
135
+ <div
136
+ class={
137
+ !this.showResult
138
+ ? 's-search-modal-search-box-inner'
139
+ : 's-search-modal-search-box-inner-open'
140
+ }
141
+ >
142
+ <input
143
+ class="s-search-modal-input"
144
+ type="text"
145
+ placeholder={this.searchPlaceholder}
146
+ value={this.searchTerm}
147
+ onInput={event => this.handleChange(event)}
148
+ />
149
+
150
+ {this.fetchStatus != 'loading' ? (
151
+ <button class="s-search-modal-search-icon">
152
+ <i class="sicon-search"></i>
153
+ </button>
154
+ ) : (
155
+ <span class="s-search-modal-spinner">
156
+ <span class="s-search-modal-spinner-loader"></span>
157
+ </span>
158
+ )}
159
+ </div>
160
+ </div>
161
+
162
+ {/* results */}
163
+ <div class="s-search-modal-search-results">
164
+ {this.fetchStatus === 'error' && (
165
+ <p class="s-search-modal-no-results error p-4 text-sm text-gray-text">
166
+ {this.noResultsText}
167
+ </p>
168
+ )}
169
+
170
+ {this.results &&
171
+ this.results.map(item => {
172
+ return this.getProduct(item);
173
+ })}
174
+ </div>
175
+ </div>
176
+ </div>
177
+ </div>
178
+ )}
179
+ </Host>
180
+ );
181
+ }
182
+ }
@@ -0,0 +1 @@
1
+ [{"title":"salla-salla-login","file":"salla-login/readme.md"},{"title":"salla-search-modal","file":"search-modal/readme.md"}]
@@ -0,0 +1,76 @@
1
+ /* eslint-disable */
2
+ /* tslint:disable */
3
+ /**
4
+ * This is an autogenerated file created by the Stencil compiler.
5
+ * It contains typing information for all components that exist in this project.
6
+ */
7
+ import { HTMLStencilElement, JSXBase } from "@stencil/core/internal";
8
+ export namespace Components {
9
+ interface SallaLogin {
10
+ "searchIcon": string;
11
+ /**
12
+ * If 'true' will make the modal visible.
13
+ */
14
+ "visible": boolean;
15
+ }
16
+ interface SallaSearchModal {
17
+ /**
18
+ * The text to overwrite no results text.
19
+ */
20
+ "noResultsText": string;
21
+ /**
22
+ * The text to overwrite search placeholder.
23
+ */
24
+ "searchPlaceholder": string;
25
+ }
26
+ }
27
+ declare global {
28
+ interface HTMLSallaLoginElement extends Components.SallaLogin, HTMLStencilElement {
29
+ }
30
+ var HTMLSallaLoginElement: {
31
+ prototype: HTMLSallaLoginElement;
32
+ new (): HTMLSallaLoginElement;
33
+ };
34
+ interface HTMLSallaSearchModalElement extends Components.SallaSearchModal, HTMLStencilElement {
35
+ }
36
+ var HTMLSallaSearchModalElement: {
37
+ prototype: HTMLSallaSearchModalElement;
38
+ new (): HTMLSallaSearchModalElement;
39
+ };
40
+ interface HTMLElementTagNameMap {
41
+ "salla-login": HTMLSallaLoginElement;
42
+ "salla-search-modal": HTMLSallaSearchModalElement;
43
+ }
44
+ }
45
+ declare namespace LocalJSX {
46
+ interface SallaLogin {
47
+ "searchIcon"?: string;
48
+ /**
49
+ * If 'true' will make the modal visible.
50
+ */
51
+ "visible"?: boolean;
52
+ }
53
+ interface SallaSearchModal {
54
+ /**
55
+ * The text to overwrite no results text.
56
+ */
57
+ "noResultsText"?: string;
58
+ /**
59
+ * The text to overwrite search placeholder.
60
+ */
61
+ "searchPlaceholder"?: string;
62
+ }
63
+ interface IntrinsicElements {
64
+ "salla-login": SallaLogin;
65
+ "salla-search-modal": SallaSearchModal;
66
+ }
67
+ }
68
+ export { LocalJSX as JSX };
69
+ declare module "@stencil/core" {
70
+ export namespace JSX {
71
+ interface IntrinsicElements {
72
+ "salla-login": LocalJSX.SallaLogin & JSXBase.HTMLAttributes<HTMLSallaLoginElement>;
73
+ "salla-search-modal": LocalJSX.SallaSearchModal & JSXBase.HTMLAttributes<HTMLSallaSearchModalElement>;
74
+ }
75
+ }
76
+ }