setmy-info-less-ide 3.1.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 +39 -0
- package/cucumber.js +10 -0
- package/dist/main.css +118 -0
- package/dist/main.min.css +1 -0
- package/jest.config.js +10 -0
- package/jest.e2e.config.js +5 -0
- package/package.json +60 -0
- package/playwright.config.js +9 -0
- package/src/main/less/experimental/experimental-frames-colors.less +35 -0
- package/src/main/less/experimental/main.less +4 -0
- package/src/main/less/frames/index.less +135 -0
- package/src/main/less/main.less +35 -0
- package/src/main/less/utility/index.less +1 -0
- package/src/test/gherkin/body.feature +20 -0
- package/src/test/gherkin/experimental-frames.feature +17 -0
- package/src/test/gherkin/frames.feature +19 -0
- package/src/test/js/e2e/body.e2e.js +40 -0
- package/src/test/js/e2e/frames.e2e.js +60 -0
- package/src/test/pug/body.pug +4 -0
- package/src/test/pug/experimental-frames.pug +152 -0
- package/src/test/pug/frames.pug +11 -0
- package/src/test/pug/include/head.pug +10 -0
- package/stylelint.config.js +19 -0
package/README.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# setmy-info-less-ide
|
|
2
|
+
|
|
3
|
+
CSS patterns for developer-facing UIs: code editors, debugging panels, output consoles,
|
|
4
|
+
split-pane workspaces, and developer dashboards. Extends the enterprise package with
|
|
5
|
+
patterns specific to developer tool web applications, including the NetBeans-style frame shell.
|
|
6
|
+
|
|
7
|
+
**Target audience:** Developers building IDE-style or developer-tool web UIs — think
|
|
8
|
+
browser-based code editors, CI dashboards, log viewers, or admin consoles for engineers.
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```shell
|
|
13
|
+
npm i setmy-info-less-ide
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Dependencies
|
|
17
|
+
|
|
18
|
+
Depends on [`setmy-info-less-enterprise`](../setmy-info-less-enterprise/README.md), which
|
|
19
|
+
provides the stable shared stack beneath this IDE-specific layer.
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
Load the enterprise compiled CSS (includes everything) plus this package:
|
|
24
|
+
|
|
25
|
+
```html
|
|
26
|
+
<link rel="stylesheet" href="node_modules/setmy-info-less-enterprise/dist/main.min.css">
|
|
27
|
+
<link rel="stylesheet" href="node_modules/setmy-info-less-ide/dist/main.css">
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The IDE package now owns the NetBeans-style frame selectors such as
|
|
31
|
+
`body.framesDefaultPadding`, `.contentHeader`, `.sectionLeft`, and `.sectionRightBottom`.
|
|
32
|
+
|
|
33
|
+
## Development
|
|
34
|
+
|
|
35
|
+
```shell
|
|
36
|
+
npm run build
|
|
37
|
+
npm run lint:less
|
|
38
|
+
npm run verify
|
|
39
|
+
```
|
package/cucumber.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
default: [
|
|
3
|
+
`--format-options '{"snippetInterface": "synchronous"}'`,
|
|
4
|
+
'--require ../common/test/js/bdd/support.js',
|
|
5
|
+
'--require ../common/test/js/bdd/given.js',
|
|
6
|
+
'--require ../common/test/js/bdd/when.js',
|
|
7
|
+
'--require ../common/test/js/bdd/then.js',
|
|
8
|
+
'./src/test/gherkin'
|
|
9
|
+
].join(' ')
|
|
10
|
+
};
|
package/dist/main.css
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Main entry point for the IDE module.
|
|
3
|
+
|
|
4
|
+
CSS patterns for developer-facing UIs: code editors, debugging panels, output consoles,
|
|
5
|
+
developer dashboards.
|
|
6
|
+
|
|
7
|
+
Distribution model: STANDALONE / DELTA.
|
|
8
|
+
`dist/main.css` contains ONLY this package's own rules — the NetBeans-style frame presets in
|
|
9
|
+
`frames/index.less` (plus anything added under `utility/`). It does NOT bundle base or enterprise
|
|
10
|
+
CSS. Consumers load the stylesheets in dependency order:
|
|
11
|
+
|
|
12
|
+
setmy-info-less-enterprise -> setmy-info-less-ide
|
|
13
|
+
|
|
14
|
+
The dependency on `setmy-info-less-enterprise` is a load-order relationship declared in
|
|
15
|
+
package.json (load the enterprise CSS, which carries the full stable stack, before this file), not
|
|
16
|
+
a CSS import — enterprise's rules must not be bundled into this delta. The base module's
|
|
17
|
+
`values/index.less` is imported below for TOKENS ONLY (LESS variables emit no CSS), so the frame
|
|
18
|
+
rules can reference shared variables without re-emitting base or enterprise styles.
|
|
19
|
+
*/
|
|
20
|
+
/* Base tokens only (no CSS output) — gives the frame rules access to shared variables */
|
|
21
|
+
/* values/main.less */
|
|
22
|
+
/* values/colors/main.less */
|
|
23
|
+
/* values/fonts/main.less */
|
|
24
|
+
/* This package's own rules */
|
|
25
|
+
/*
|
|
26
|
+
Frame presets for the IDE module.
|
|
27
|
+
|
|
28
|
+
These rules provide a NetBeans-inspired application shell layout. They mix utility-like
|
|
29
|
+
classes with structural selectors such as `body.framesDefaultPadding` and rely on modern
|
|
30
|
+
layout math through `calc(...)`.
|
|
31
|
+
|
|
32
|
+
If very old browser support is required later, this file is one of the first places to review.
|
|
33
|
+
*/
|
|
34
|
+
body.framesDefaultPadding {
|
|
35
|
+
/* stylelint-disable-next-line declaration-property-value-no-unknown */
|
|
36
|
+
height: calc(100% - 0px);
|
|
37
|
+
/* stylelint-disable-next-line declaration-property-value-no-unknown */
|
|
38
|
+
width: calc(100% - 0px);
|
|
39
|
+
padding: 0px;
|
|
40
|
+
}
|
|
41
|
+
.contentHeader {
|
|
42
|
+
width: 100%;
|
|
43
|
+
height: 50px;
|
|
44
|
+
}
|
|
45
|
+
.defaultHeader {
|
|
46
|
+
width: 100%;
|
|
47
|
+
height: 25px;
|
|
48
|
+
}
|
|
49
|
+
.content {
|
|
50
|
+
width: 100%;
|
|
51
|
+
/* stylelint-disable-next-line declaration-property-value-no-unknown */
|
|
52
|
+
height: calc(100% - 75px);
|
|
53
|
+
}
|
|
54
|
+
.contentFooter {
|
|
55
|
+
width: 100%;
|
|
56
|
+
height: 25px;
|
|
57
|
+
}
|
|
58
|
+
.sectionLeft {
|
|
59
|
+
/* stylelint-disable-next-line declaration-property-value-no-unknown */
|
|
60
|
+
width: calc(30% - 8px - 4px);
|
|
61
|
+
height: 100%;
|
|
62
|
+
}
|
|
63
|
+
.verticalSeparator {
|
|
64
|
+
width: 8px;
|
|
65
|
+
height: 100%;
|
|
66
|
+
display: block;
|
|
67
|
+
}
|
|
68
|
+
.sectionRight {
|
|
69
|
+
width: 70%;
|
|
70
|
+
height: 100%;
|
|
71
|
+
}
|
|
72
|
+
.sectionHeader {
|
|
73
|
+
width: 100%;
|
|
74
|
+
height: 25px;
|
|
75
|
+
}
|
|
76
|
+
.sectionLeftUp {
|
|
77
|
+
width: 100%;
|
|
78
|
+
/* stylelint-disable-next-line declaration-property-value-no-unknown */
|
|
79
|
+
height: calc(60% - 4px - 8px);
|
|
80
|
+
}
|
|
81
|
+
.contentLeftUp {
|
|
82
|
+
width: 100%;
|
|
83
|
+
/* stylelint-disable-next-line declaration-property-value-no-unknown */
|
|
84
|
+
height: calc(100% - 25px);
|
|
85
|
+
}
|
|
86
|
+
.horizontalSeparator {
|
|
87
|
+
height: 4px;
|
|
88
|
+
}
|
|
89
|
+
.sectionLeftBottom {
|
|
90
|
+
width: 100%;
|
|
91
|
+
/* stylelint-disable-next-line declaration-property-value-no-unknown */
|
|
92
|
+
height: calc(40%);
|
|
93
|
+
}
|
|
94
|
+
.contentLeftBottom {
|
|
95
|
+
width: 100%;
|
|
96
|
+
/* stylelint-disable-next-line declaration-property-value-no-unknown */
|
|
97
|
+
height: calc(100% - 25px);
|
|
98
|
+
}
|
|
99
|
+
.sectionRightUp {
|
|
100
|
+
width: 100%;
|
|
101
|
+
height: 30%;
|
|
102
|
+
}
|
|
103
|
+
.contentRightUp {
|
|
104
|
+
width: 100%;
|
|
105
|
+
/* stylelint-disable-next-line declaration-property-value-no-unknown */
|
|
106
|
+
height: calc(100% - 25px);
|
|
107
|
+
}
|
|
108
|
+
.sectionRightBottom {
|
|
109
|
+
width: 100%;
|
|
110
|
+
/* stylelint-disable-next-line declaration-property-value-no-unknown */
|
|
111
|
+
height: calc(70% - 4px - 8px);
|
|
112
|
+
}
|
|
113
|
+
.contentRightBottom {
|
|
114
|
+
width: 100%;
|
|
115
|
+
/* stylelint-disable-next-line declaration-property-value-no-unknown */
|
|
116
|
+
height: calc(100% - 25px);
|
|
117
|
+
}
|
|
118
|
+
/* IDE utility classes — add imports here as the module grows. */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
body.framesDefaultPadding{height:calc(100% - 0px);width:calc(100% - 0px);padding:0}.contentHeader{width:100%;height:50px}.defaultHeader{width:100%;height:25px}.content{width:100%;height:calc(100% - 75px)}.contentFooter{width:100%;height:25px}.sectionLeft{width:calc(30% - 8px - 4px);height:100%}.verticalSeparator{width:8px;height:100%;display:block}.sectionRight{width:70%;height:100%}.sectionHeader{width:100%;height:25px}.sectionLeftUp{width:100%;height:calc(60% - 4px - 8px)}.contentLeftUp{width:100%;height:calc(100% - 25px)}.horizontalSeparator{height:4px}.sectionLeftBottom{width:100%;height:calc(40%)}.contentLeftBottom{width:100%;height:calc(100% - 25px)}.sectionRightUp{width:100%;height:30%}.contentRightUp{width:100%;height:calc(100% - 25px)}.sectionRightBottom{width:100%;height:calc(70% - 4px - 8px)}.contentRightBottom{width:100%;height:calc(100% - 25px)}
|
package/jest.config.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "setmy-info-less-ide",
|
|
3
|
+
"version": "3.1.0",
|
|
4
|
+
"description": "SMI LESS IDE — developer tool and IDE-style UI patterns, builds on the enterprise package",
|
|
5
|
+
"main": "dist/main.min.css",
|
|
6
|
+
"dependencies": {
|
|
7
|
+
"setmy-info-less-enterprise": "*"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "npm run css && npm run css-min && npm run css:experimental && npm run html && npm run styleguide",
|
|
11
|
+
"build:experimental": "npm run css:experimental",
|
|
12
|
+
"css": "lessc ./src/main/less/main.less dist/main.css",
|
|
13
|
+
"css:experimental": "lessc ./src/main/less/experimental/main.less dist/experimental.css",
|
|
14
|
+
"css-min": "lessc ./src/main/less/main.less dist/main.min.css --clean-css",
|
|
15
|
+
"html": "node ../common/test/js/pugBuild.js",
|
|
16
|
+
"start": "node ../common/test/js/server.js",
|
|
17
|
+
"watch": "less-watch-compiler ./src/main/less dist main.less",
|
|
18
|
+
"watch:pug": "node ../common/test/js/pugWatch.js",
|
|
19
|
+
"clean": "rimraf dist",
|
|
20
|
+
"clean:all": "rimraf dist node_modules",
|
|
21
|
+
"verify": "npm test && npm run e2e && npm run lint:less && npm run cucumber",
|
|
22
|
+
"test": "jest",
|
|
23
|
+
"e2e": "jest --config=jest.e2e.config.js",
|
|
24
|
+
"e2e:one": "jest --config=jest.e2e.config.js --testNamePattern",
|
|
25
|
+
"cucumber": "cucumber-js",
|
|
26
|
+
"lint:less": "stylelint ./src/main/less/**/*.less",
|
|
27
|
+
"lint:fix-less": "stylelint ./src/main/less/**/*.less --fix",
|
|
28
|
+
"styleguide": "kss-node --source src/main/less --destination dist/styleguide --css ../main.css"
|
|
29
|
+
},
|
|
30
|
+
"keywords": [
|
|
31
|
+
"less",
|
|
32
|
+
"css",
|
|
33
|
+
"ide",
|
|
34
|
+
"developer",
|
|
35
|
+
"tools"
|
|
36
|
+
],
|
|
37
|
+
"author": "Imre Tabur <imre.tabur@mail.ee>",
|
|
38
|
+
"license": "MIT",
|
|
39
|
+
"repository": {
|
|
40
|
+
"type": "git",
|
|
41
|
+
"url": "https://github.com/setmy-info/setmy-info-less.git"
|
|
42
|
+
},
|
|
43
|
+
"homepage": "https://github.com/setmy-info/setmy-info-less",
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@cucumber/cucumber": "^13.0.0",
|
|
46
|
+
"express": "^5.2.1",
|
|
47
|
+
"jest": "^30.4.2",
|
|
48
|
+
"kss": "^2.4.0",
|
|
49
|
+
"less": "^4.6.6",
|
|
50
|
+
"less-plugin-clean-css": "^1.6.0",
|
|
51
|
+
"less-watch-compiler": "^1.17.5",
|
|
52
|
+
"postcss-less": "^6.0.0",
|
|
53
|
+
"selenium-webdriver": "^4.45.0",
|
|
54
|
+
"pug": "^3.0.4",
|
|
55
|
+
"rimraf": "^6.1.3",
|
|
56
|
+
"stylelint": "^17.13.0",
|
|
57
|
+
"stylelint-config-standard": "^40.0.0",
|
|
58
|
+
"stylelint-less": "^4.2.1"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/*
|
|
2
|
+
LEGACY STUB — retained intentionally, kept empty on purpose (not removed).
|
|
3
|
+
|
|
4
|
+
Playwright is no longer used: e2e tests run via an external Selenium Grid through the Jest
|
|
5
|
+
runner (see jest.e2e.config.js and ../common/test/js/pageHelper.js). This empty config remains
|
|
6
|
+
as a marker of the migration and to avoid breaking any tooling or muscle-memory that still
|
|
7
|
+
references a playwright.config.js. It is deliberately a no-op and exports nothing meaningful.
|
|
8
|
+
*/
|
|
9
|
+
module.exports = {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
.AliceBlue {
|
|
2
|
+
background: @blue-300;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.MoreBlue {
|
|
6
|
+
background: @blue-600;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.blanchedalmond {
|
|
10
|
+
background: blanchedalmond;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.Aquamarine {
|
|
14
|
+
background: aquamarine;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.Beige {
|
|
18
|
+
background: beige;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.Bisque {
|
|
22
|
+
background: bisque;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.BurlyWood {
|
|
26
|
+
background: burlywood;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.Cornsilk {
|
|
30
|
+
background: cornsilk;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.Cyan {
|
|
34
|
+
background: cyan;
|
|
35
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Frame presets for the IDE module.
|
|
3
|
+
|
|
4
|
+
These rules provide a NetBeans-inspired application shell layout. They mix utility-like
|
|
5
|
+
classes with structural selectors such as `body.framesDefaultPadding` and rely on modern
|
|
6
|
+
layout math through `calc(...)`.
|
|
7
|
+
|
|
8
|
+
If very old browser support is required later, this file is one of the first places to review.
|
|
9
|
+
*/
|
|
10
|
+
@numberOfMenuPanels: 2;
|
|
11
|
+
@frameHeaderHeight: @numberOfMenuPanels * @halfDefaultHeight;
|
|
12
|
+
@frameFooterHeight: @halfDefaultHeight;
|
|
13
|
+
|
|
14
|
+
@sectionHeaderHeight: @halfDefaultHeight;
|
|
15
|
+
|
|
16
|
+
@verticalSeparatorWidth: 8px;
|
|
17
|
+
@horizontalSeparatorHeight: 4px;
|
|
18
|
+
|
|
19
|
+
@paddingValue: 0px;
|
|
20
|
+
@doublePaddingValue: @paddingValue * 2;
|
|
21
|
+
|
|
22
|
+
@headerFooterSum: @frameHeaderHeight + @frameFooterHeight;
|
|
23
|
+
|
|
24
|
+
body.framesDefaultPadding {
|
|
25
|
+
/* stylelint-disable-next-line declaration-property-value-no-unknown */
|
|
26
|
+
height: calc(100% - @doublePaddingValue);
|
|
27
|
+
/* stylelint-disable-next-line declaration-property-value-no-unknown */
|
|
28
|
+
width: calc(100% - @doublePaddingValue);
|
|
29
|
+
padding: @paddingValue;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.contentHeader {
|
|
33
|
+
width: 100%;
|
|
34
|
+
height: @frameHeaderHeight;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.defaultHeader {
|
|
38
|
+
width: 100%;
|
|
39
|
+
height: @halfDefaultHeight
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.content {
|
|
43
|
+
width: 100%;
|
|
44
|
+
/* stylelint-disable-next-line declaration-property-value-no-unknown */
|
|
45
|
+
height: calc(100% - @headerFooterSum);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.contentFooter {
|
|
49
|
+
width: 100%;
|
|
50
|
+
height: @frameFooterHeight;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
@leftWidth: 30%;
|
|
54
|
+
@rightWidth: 100% - @leftWidth;
|
|
55
|
+
|
|
56
|
+
.sectionLeft {
|
|
57
|
+
/* stylelint-disable-next-line declaration-property-value-no-unknown */
|
|
58
|
+
width: calc(@leftWidth - @verticalSeparatorWidth - @defaultBorderVerticalAmount);
|
|
59
|
+
height: 100%;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.verticalSeparator {
|
|
63
|
+
width: @verticalSeparatorWidth;
|
|
64
|
+
height: 100%;
|
|
65
|
+
display: block;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.sectionRight {
|
|
69
|
+
width: @rightWidth;
|
|
70
|
+
height: 100%;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.sectionHeader {
|
|
74
|
+
width: 100%;
|
|
75
|
+
height: @sectionHeaderHeight;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
@contentLeftUpHeight: 60%;
|
|
79
|
+
@contentLeftBottomHeight: 100% - @contentLeftUpHeight;
|
|
80
|
+
@doubleDefaultBorderHorizontalAmount: 2 * @defaultBorderHorizontalAmount;
|
|
81
|
+
@x: @horizontalSeparatorHeight - @doubleDefaultBorderHorizontalAmount;
|
|
82
|
+
|
|
83
|
+
.sectionLeftUp {
|
|
84
|
+
width: 100%;
|
|
85
|
+
/* stylelint-disable-next-line declaration-property-value-no-unknown */
|
|
86
|
+
height: calc(@contentLeftUpHeight - @horizontalSeparatorHeight - @doubleDefaultBorderHorizontalAmount);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.contentLeftUp {
|
|
90
|
+
width: 100%;
|
|
91
|
+
/* stylelint-disable-next-line declaration-property-value-no-unknown */
|
|
92
|
+
height: calc(100% - @sectionHeaderHeight);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.horizontalSeparator {
|
|
96
|
+
height: @horizontalSeparatorHeight;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.sectionLeftBottom {
|
|
100
|
+
width: 100%;
|
|
101
|
+
/* stylelint-disable-next-line declaration-property-value-no-unknown */
|
|
102
|
+
height: calc(@contentLeftBottomHeight);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.contentLeftBottom {
|
|
106
|
+
width: 100%;
|
|
107
|
+
/* stylelint-disable-next-line declaration-property-value-no-unknown */
|
|
108
|
+
height: calc(100% - @sectionHeaderHeight);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
@contentRightUpHeight: 30%;
|
|
112
|
+
@contentRightBottomHeight: 100% - @contentRightUpHeight;
|
|
113
|
+
|
|
114
|
+
.sectionRightUp {
|
|
115
|
+
width: 100%;
|
|
116
|
+
height: @contentRightUpHeight;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.contentRightUp {
|
|
120
|
+
width: 100%;
|
|
121
|
+
/* stylelint-disable-next-line declaration-property-value-no-unknown */
|
|
122
|
+
height: calc(100% - @sectionHeaderHeight);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.sectionRightBottom {
|
|
126
|
+
width: 100%;
|
|
127
|
+
/* stylelint-disable-next-line declaration-property-value-no-unknown */
|
|
128
|
+
height: calc(@contentRightBottomHeight - @horizontalSeparatorHeight - @doubleDefaultBorderHorizontalAmount);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.contentRightBottom {
|
|
132
|
+
width: 100%;
|
|
133
|
+
/* stylelint-disable-next-line declaration-property-value-no-unknown */
|
|
134
|
+
height: calc(100% - @sectionHeaderHeight);
|
|
135
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Main entry point for the IDE module.
|
|
3
|
+
|
|
4
|
+
CSS patterns for developer-facing UIs: code editors, debugging panels, output consoles,
|
|
5
|
+
developer dashboards.
|
|
6
|
+
|
|
7
|
+
Distribution model: STANDALONE / DELTA.
|
|
8
|
+
`dist/main.css` contains ONLY this package's own rules — the NetBeans-style frame presets in
|
|
9
|
+
`frames/index.less` (plus anything added under `utility/`). It does NOT bundle base or enterprise
|
|
10
|
+
CSS. Consumers load the stylesheets in dependency order:
|
|
11
|
+
|
|
12
|
+
setmy-info-less-enterprise -> setmy-info-less-ide
|
|
13
|
+
|
|
14
|
+
The dependency on `setmy-info-less-enterprise` is a load-order relationship declared in
|
|
15
|
+
package.json (load the enterprise CSS, which carries the full stable stack, before this file), not
|
|
16
|
+
a CSS import — enterprise's rules must not be bundled into this delta. The base module's
|
|
17
|
+
`values/index.less` is imported below for TOKENS ONLY (LESS variables emit no CSS), so the frame
|
|
18
|
+
rules can reference shared variables without re-emitting base or enterprise styles.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
// IDE module
|
|
22
|
+
//
|
|
23
|
+
// Developer-tooling UI patterns layered on the enterprise package, intended for editor panes,
|
|
24
|
+
// debug views, and NetBeans-style workbench layouts. Load the enterprise CSS before this file.
|
|
25
|
+
//
|
|
26
|
+
// Markup: <div class="smi-pane"></div>
|
|
27
|
+
//
|
|
28
|
+
// Styleguide: packages.ide
|
|
29
|
+
|
|
30
|
+
/* Base tokens only (no CSS output) — gives the frame rules access to shared variables */
|
|
31
|
+
@import url("../../../../setmy-info-less/src/main/less/values/index.less");
|
|
32
|
+
|
|
33
|
+
/* This package's own rules */
|
|
34
|
+
@import url("frames/index.less");
|
|
35
|
+
@import url("utility/index.less");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/* IDE utility classes — add imports here as the module grows. */
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Feature: body page
|
|
2
|
+
|
|
3
|
+
Scenario: body rendering with specific properties
|
|
4
|
+
Given page name is "body"
|
|
5
|
+
When page is rendered
|
|
6
|
+
And page element ID is "body"
|
|
7
|
+
Then page should have title "body.html"
|
|
8
|
+
And page element margin should be "0px 0px 0px 0px"
|
|
9
|
+
And page element padding should be "0px 0px 0px 0px"
|
|
10
|
+
And page element font family should be "DejaVu Serif, Roboto, Arial, Noto Sans, Noto, sans-serif"
|
|
11
|
+
And page element font size should be "16px"
|
|
12
|
+
And page element X should be 0
|
|
13
|
+
And page element Y should be 0
|
|
14
|
+
And page element WIDTH should be 2000
|
|
15
|
+
And page element HEIGHT should be 1200
|
|
16
|
+
And page element TOP should be 0
|
|
17
|
+
And page element LEFT should be 0
|
|
18
|
+
And page element background color should be "rgba(0, 0, 0, 0)"
|
|
19
|
+
And page element color should be "rgb(0, 0, 0)"
|
|
20
|
+
And page is closed
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Feature: IDE experimental frames page
|
|
2
|
+
|
|
3
|
+
Scenario: experimental frames page is generated from the IDE workspace
|
|
4
|
+
Given page name is "experimental-frames"
|
|
5
|
+
When page is rendered
|
|
6
|
+
And page element ID is "body"
|
|
7
|
+
Then page should have title "experimental-frames.html"
|
|
8
|
+
And page element padding should be "0px 0px 0px 0px"
|
|
9
|
+
And page element ID is "verticalDivider"
|
|
10
|
+
And page element WIDTH should be 8
|
|
11
|
+
And page element ID is "horizontalLeftDivider"
|
|
12
|
+
And page element HEIGHT should be 4
|
|
13
|
+
And page element ID is "horizontalRightDivider"
|
|
14
|
+
And page element HEIGHT should be 4
|
|
15
|
+
And page element ID is "body"
|
|
16
|
+
And page element style "cursor" should be "auto"
|
|
17
|
+
And page is closed
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Feature: IDE frames page
|
|
2
|
+
|
|
3
|
+
Scenario: NetBeans-style frame layout is provided by the IDE package
|
|
4
|
+
Given page name is "frames"
|
|
5
|
+
When page is rendered
|
|
6
|
+
And page element ID is "body"
|
|
7
|
+
Then page should have title "frames.html"
|
|
8
|
+
And page element padding should be "0px 0px 0px 0px"
|
|
9
|
+
And page element ID is "contentHeader"
|
|
10
|
+
And page element HEIGHT should be 50
|
|
11
|
+
And page element ID is "content"
|
|
12
|
+
And page element HEIGHT should be 1125
|
|
13
|
+
And page element ID is "sectionLeft"
|
|
14
|
+
And page element WIDTH should be 588
|
|
15
|
+
And page element ID is "verticalSeparator"
|
|
16
|
+
And page element WIDTH should be 8
|
|
17
|
+
And page element ID is "contentFooter"
|
|
18
|
+
And page element HEIGHT should be 25
|
|
19
|
+
And page is closed
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const pageHelper = require('../../../../../common/test/js/pageHelper');
|
|
2
|
+
const getTestPageName = require('../../../../../common/test/js/testPageName');
|
|
3
|
+
|
|
4
|
+
const pageName = getTestPageName();
|
|
5
|
+
|
|
6
|
+
describe(pageName + ' page layout tests', () => {
|
|
7
|
+
|
|
8
|
+
beforeAll(async () => {
|
|
9
|
+
pageHelper.pageName(pageName);
|
|
10
|
+
await pageHelper.pageIsRendered();
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
afterAll(async () => {
|
|
14
|
+
await pageHelper.pageClose();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test('should load the page and check title', async () => {
|
|
18
|
+
|
|
19
|
+
const title = await pageHelper.getTitle();
|
|
20
|
+
expect(title).toBe('body.html');
|
|
21
|
+
|
|
22
|
+
await pageHelper.elementExpectations(
|
|
23
|
+
'body',
|
|
24
|
+
{
|
|
25
|
+
margin: '0px 0px 0px 0px',
|
|
26
|
+
padding: '0px 0px 0px 0px',
|
|
27
|
+
fontFamily: 'DejaVu Serif, Roboto, Arial, Noto Sans, Noto, sans-serif',
|
|
28
|
+
fontSize: '16px',
|
|
29
|
+
x: 0,
|
|
30
|
+
y: 0,
|
|
31
|
+
width: 2000,
|
|
32
|
+
height: 1200,
|
|
33
|
+
top: 0,
|
|
34
|
+
left: 0,
|
|
35
|
+
backgroundColor: 'rgba(0, 0, 0, 0)',
|
|
36
|
+
color: 'rgb(0, 0, 0)'
|
|
37
|
+
}
|
|
38
|
+
);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
const pageHelper = require('../../../../../common/test/js/pageHelper');
|
|
2
|
+
const getTestPageName = require('../../../../../common/test/js/testPageName');
|
|
3
|
+
|
|
4
|
+
const pageName = getTestPageName();
|
|
5
|
+
|
|
6
|
+
// NetBeans-style IDE frame layout (frames/index.less). Viewport is 2000x1200.
|
|
7
|
+
// Expected geometry (see frames/index.less):
|
|
8
|
+
// frameHeaderHeight = 2 * halfDefaultHeight = 50px
|
|
9
|
+
// frameFooterHeight = halfDefaultHeight = 25px
|
|
10
|
+
// content height = 1200 - (50 + 25) = 1125px
|
|
11
|
+
// sectionLeft width = 30% * 2000 - 8 - 4 = 588px
|
|
12
|
+
// verticalSeparator = 8px
|
|
13
|
+
// sectionRight width = 70% * 2000 = 1400px
|
|
14
|
+
describe(pageName + ' frame layout tests', () => {
|
|
15
|
+
|
|
16
|
+
beforeAll(async () => {
|
|
17
|
+
pageHelper.pageName(pageName);
|
|
18
|
+
await pageHelper.pageIsRendered();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
afterAll(async () => {
|
|
22
|
+
await pageHelper.pageClose();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
test('should load the page and check title', async () => {
|
|
26
|
+
expect(await pageHelper.getTitle()).toBe('frames.html');
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test('contentHeader fills width and is one header tall', async () => {
|
|
30
|
+
await pageHelper.elementIdIs('contentHeader');
|
|
31
|
+
expect(pageHelper.data.computedStyles.height).toBe(50);
|
|
32
|
+
expect(pageHelper.data.computedStyles.width).toBe(2000);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test('content takes the remaining height', async () => {
|
|
36
|
+
await pageHelper.elementIdIs('content');
|
|
37
|
+
expect(pageHelper.data.computedStyles.height).toBe(1125);
|
|
38
|
+
expect(pageHelper.data.computedStyles.width).toBe(2000);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test('contentFooter is half a default height tall', async () => {
|
|
42
|
+
await pageHelper.elementIdIs('contentFooter');
|
|
43
|
+
expect(pageHelper.data.computedStyles.height).toBe(25);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test('sectionLeft is the left 30% pane minus separator and borders', async () => {
|
|
47
|
+
await pageHelper.elementIdIs('sectionLeft');
|
|
48
|
+
expect(pageHelper.data.computedStyles.width).toBe(588);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
test('verticalSeparator is 8px wide', async () => {
|
|
52
|
+
await pageHelper.elementIdIs('verticalSeparator');
|
|
53
|
+
expect(pageHelper.data.computedStyles.width).toBe(8);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test('sectionRight is the right 70% pane', async () => {
|
|
57
|
+
await pageHelper.elementIdIs('sectionRight');
|
|
58
|
+
expect(pageHelper.data.computedStyles.width).toBe(1400);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
doctype html
|
|
2
|
+
html(lang="en")
|
|
3
|
+
head(id="head")
|
|
4
|
+
title experimental-frames.html
|
|
5
|
+
meta(charset="UTF-8")
|
|
6
|
+
meta(name="viewport", content="width=device-width, initial-scale=1.0")
|
|
7
|
+
meta(name="description", content="HTML 5 CSS test pages")
|
|
8
|
+
meta(name="author", content="Imre Tabur")
|
|
9
|
+
link(rel="stylesheet", type="text/css", href="../../setmy-info-less/dist/main.min.css")
|
|
10
|
+
link(rel="stylesheet", type="text/css", href="main.css")
|
|
11
|
+
link(rel="stylesheet", type="text/css", href="experimental.css")
|
|
12
|
+
body(id="body" class="framesDefaultPadding")
|
|
13
|
+
header(class="contentHeader AliceBlue")
|
|
14
|
+
menu
|
|
15
|
+
li(class="floatLeft Aquamarine halfHeight") Floating left A
|
|
16
|
+
li(class="floatLeft Aquamarine halfHeight") Floating left B
|
|
17
|
+
li(class="floatRight Aquamarine halfHeight") Floating right B
|
|
18
|
+
li(class="floatRight Aquamarine halfHeight") Floating right A
|
|
19
|
+
li(class="floatClear")
|
|
20
|
+
menu
|
|
21
|
+
li(class="floatLeft Aquamarine halfHeight") Floating left A
|
|
22
|
+
li(class="floatLeft Aquamarine halfHeight") Floating left B
|
|
23
|
+
li(class="floatRight Aquamarine halfHeight") Floating right B
|
|
24
|
+
li(class="floatRight Aquamarine halfHeight") Floating right A
|
|
25
|
+
li(class="floatClear")
|
|
26
|
+
main(class="content")
|
|
27
|
+
section(class="sectionLeft floatLeft")
|
|
28
|
+
div(class="sectionLeftUp defaultBorder")
|
|
29
|
+
header(class="sectionHeader AliceBlue")
|
|
30
|
+
menu
|
|
31
|
+
li(class="floatLeft Aquamarine halfHeight") A
|
|
32
|
+
li(class="floatLeft Aquamarine halfHeight") B
|
|
33
|
+
li(class="floatRight Aquamarine halfHeight") B
|
|
34
|
+
li(class="floatRight Aquamarine halfHeight") A
|
|
35
|
+
li(class="floatClear")
|
|
36
|
+
div(class="contentLeftUp noWrap autoScrollBars Beige")
|
|
37
|
+
- for (let i = 0; i < 50; i++)
|
|
38
|
+
div Left Up #{i} Longer Longer Longer Longer Longer Longer Longer Longer Longer
|
|
39
|
+
div(id="horizontalLeftDivider" class="horizontalSeparator cursorHorizontalResize")
|
|
40
|
+
div(class="sectionLeftBottom defaultBorder")
|
|
41
|
+
header(class="sectionHeader AliceBlue")
|
|
42
|
+
menu
|
|
43
|
+
li(class="floatLeft Aquamarine halfHeight") A
|
|
44
|
+
li(class="floatLeft Aquamarine halfHeight") B
|
|
45
|
+
li(class="floatRight Aquamarine halfHeight") B
|
|
46
|
+
li(class="floatRight Aquamarine halfHeight") A
|
|
47
|
+
li(class="floatClear")
|
|
48
|
+
div(class="contentLeftBottom noWrap autoScrollBars Bisque")
|
|
49
|
+
- for (let i = 0; i < 50; i++)
|
|
50
|
+
div Left Up #{i} Longer Longer Longer Longer Longer Longer Longer Longer Longer
|
|
51
|
+
div(id="verticalDivider" class="verticalSeparator cursorVerticalResize floatLeft")
|
|
52
|
+
section(class="sectionRight floatLeft")
|
|
53
|
+
div(class="sectionRightUp defaultBorder")
|
|
54
|
+
header(class="sectionHeader AliceBlue")
|
|
55
|
+
menu
|
|
56
|
+
li(class="floatLeft Aquamarine halfHeight") A
|
|
57
|
+
li(class="floatLeft Aquamarine halfHeight") B
|
|
58
|
+
li(class="floatRight Aquamarine halfHeight") B
|
|
59
|
+
li(class="floatRight Aquamarine halfHeight") A
|
|
60
|
+
li(class="floatClear")
|
|
61
|
+
div(class="contentRightUp noWrap autoScrollBars BurlyWood")
|
|
62
|
+
- for (let i = 0; i < 50; i++)
|
|
63
|
+
div Left Up #{i} Longer Longer Longer Longer Longer Longer Longer Longer Longer
|
|
64
|
+
div(id="horizontalRightDivider" class="horizontalSeparator cursorHorizontalResize")
|
|
65
|
+
div(class="sectionRightBottom defaultBorder")
|
|
66
|
+
header(class="sectionHeader AliceBlue")
|
|
67
|
+
menu
|
|
68
|
+
li(class="floatLeft Aquamarine halfHeight") A
|
|
69
|
+
li(class="floatLeft Aquamarine halfHeight") B
|
|
70
|
+
li(class="floatRight Aquamarine halfHeight") B
|
|
71
|
+
li(class="floatRight Aquamarine halfHeight") A
|
|
72
|
+
li(class="floatClear")
|
|
73
|
+
div(class="contentRightBottom noWrap autoScrollBars Cornsilk")
|
|
74
|
+
- for (let i = 0; i < 50; i++)
|
|
75
|
+
div Left Up #{i} Longer Longer Longer Longer Longer Longer Longer Longer Longer
|
|
76
|
+
div(class="floatClear")
|
|
77
|
+
footer(class="contentFooter AliceBlue")
|
|
78
|
+
menu
|
|
79
|
+
li(class="floatLeft Aquamarine halfHeight") Floating left A
|
|
80
|
+
li(class="floatLeft Aquamarine halfHeight") Floating left B
|
|
81
|
+
li(class="floatRight Aquamarine halfHeight") Floating right B
|
|
82
|
+
li(class="floatRight Aquamarine halfHeight") Floating right A
|
|
83
|
+
li(class="floatClear")
|
|
84
|
+
|
|
85
|
+
script.
|
|
86
|
+
// Horizontal resize: the vertical divider drags the left/right panes wider/narrower.
|
|
87
|
+
function makeColumnResizer(dividerId, leftSelector, rightSelector) {
|
|
88
|
+
const divider = document.getElementById(dividerId);
|
|
89
|
+
if (!divider) return;
|
|
90
|
+
const left = document.querySelector(leftSelector);
|
|
91
|
+
const right = document.querySelector(rightSelector);
|
|
92
|
+
if (!left || !right) return;
|
|
93
|
+
let dragging = false;
|
|
94
|
+
divider.addEventListener('mousedown', function (e) {
|
|
95
|
+
dragging = true;
|
|
96
|
+
document.body.style.cursor = 'col-resize';
|
|
97
|
+
e.preventDefault();
|
|
98
|
+
});
|
|
99
|
+
document.addEventListener('mousemove', function (e) {
|
|
100
|
+
if (!dragging) return;
|
|
101
|
+
const container = divider.parentElement;
|
|
102
|
+
const rect = container.getBoundingClientRect();
|
|
103
|
+
const totalWidth = container.clientWidth;
|
|
104
|
+
const minWidth = 100;
|
|
105
|
+
const newLeftWidth = e.clientX - rect.left;
|
|
106
|
+
if (newLeftWidth < minWidth || newLeftWidth > totalWidth - minWidth - divider.offsetWidth) return;
|
|
107
|
+
left.style.width = `${newLeftWidth}px`;
|
|
108
|
+
right.style.width = `${totalWidth - newLeftWidth - divider.offsetWidth}px`;
|
|
109
|
+
});
|
|
110
|
+
document.addEventListener('mouseup', function () {
|
|
111
|
+
if (dragging) {
|
|
112
|
+
dragging = false;
|
|
113
|
+
document.body.style.cursor = 'default';
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Vertical resize: a horizontal divider drags its pane's upper/lower sections taller/shorter.
|
|
119
|
+
function makeRowResizer(dividerId, upSelector, bottomSelector) {
|
|
120
|
+
const divider = document.getElementById(dividerId);
|
|
121
|
+
if (!divider) return;
|
|
122
|
+
const up = document.querySelector(upSelector);
|
|
123
|
+
const bottom = document.querySelector(bottomSelector);
|
|
124
|
+
if (!up || !bottom) return;
|
|
125
|
+
let dragging = false;
|
|
126
|
+
divider.addEventListener('mousedown', function (e) {
|
|
127
|
+
dragging = true;
|
|
128
|
+
document.body.style.cursor = 'row-resize';
|
|
129
|
+
e.preventDefault();
|
|
130
|
+
});
|
|
131
|
+
document.addEventListener('mousemove', function (e) {
|
|
132
|
+
if (!dragging) return;
|
|
133
|
+
const container = divider.parentElement;
|
|
134
|
+
const rect = container.getBoundingClientRect();
|
|
135
|
+
const totalHeight = container.clientHeight;
|
|
136
|
+
const minHeight = 40;
|
|
137
|
+
const newUpHeight = e.clientY - rect.top;
|
|
138
|
+
if (newUpHeight < minHeight || newUpHeight > totalHeight - minHeight - divider.offsetHeight) return;
|
|
139
|
+
up.style.height = `${newUpHeight}px`;
|
|
140
|
+
bottom.style.height = `${totalHeight - newUpHeight - divider.offsetHeight}px`;
|
|
141
|
+
});
|
|
142
|
+
document.addEventListener('mouseup', function () {
|
|
143
|
+
if (dragging) {
|
|
144
|
+
dragging = false;
|
|
145
|
+
document.body.style.cursor = 'default';
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
makeColumnResizer('verticalDivider', '.sectionLeft', '.sectionRight');
|
|
151
|
+
makeRowResizer('horizontalRightDivider', '.sectionRightUp', '.sectionRightBottom');
|
|
152
|
+
makeRowResizer('horizontalLeftDivider', '.sectionLeftUp', '.sectionLeftBottom');
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
doctype html
|
|
2
|
+
html(lang="en")
|
|
3
|
+
include include/head.pug
|
|
4
|
+
body(id="body" class="framesDefaultPadding")
|
|
5
|
+
div(id="contentHeader" class="contentHeader") Header
|
|
6
|
+
main(id="content" class="content")
|
|
7
|
+
section(id="sectionLeft" class="sectionLeft floatLeft") Left
|
|
8
|
+
div(id="verticalSeparator" class="verticalSeparator floatLeft")
|
|
9
|
+
section(id="sectionRight" class="sectionRight floatLeft")
|
|
10
|
+
div(id="sectionRightBottom" class="sectionRightBottom") Right Bottom
|
|
11
|
+
div(id="contentFooter" class="contentFooter") Footer
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
head(id="head")
|
|
2
|
+
title #{title}
|
|
3
|
+
meta(charset="UTF-8")
|
|
4
|
+
meta(name="viewport", content="width=device-width, initial-scale=1.0")
|
|
5
|
+
meta(name="description", content="HTML 5 CSS test pages")
|
|
6
|
+
meta(name="author", content="Imre Tabur")
|
|
7
|
+
//- Delta model: load each module's own CSS in dependency order. extended/enterprise are
|
|
8
|
+
//- empty skeletons today, so base supplies the resets the frame layout sits on.
|
|
9
|
+
link(rel="stylesheet", type="text/css", href="../../setmy-info-less/dist/main.min.css")
|
|
10
|
+
link(rel="stylesheet", type="text/css", href="main.css")
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
customSyntax: 'postcss-less',
|
|
3
|
+
configBasedir: "src/main/less",
|
|
4
|
+
extends: [
|
|
5
|
+
'stylelint-config-standard'
|
|
6
|
+
],
|
|
7
|
+
rules: {
|
|
8
|
+
'block-no-empty': null,
|
|
9
|
+
'selector-class-pattern': null,
|
|
10
|
+
'media-feature-range-notation': 'prefix',
|
|
11
|
+
"selector-type-no-unknown": [true, {
|
|
12
|
+
ignoreTypes: ["app"]
|
|
13
|
+
}],
|
|
14
|
+
},
|
|
15
|
+
ignoreFiles: [
|
|
16
|
+
'**/node_modules/**',
|
|
17
|
+
'**/dist/**'
|
|
18
|
+
]
|
|
19
|
+
};
|