@@ -54,6 +55,104 @@ Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+
+
行高亮和聚焦
+
+
+
+
+
+
+
diff
+
+
+
+
+
+
普通示例
+
code line
code line
diff --git a/src/css/modules/code.css b/src/css/modules/code.css
index bb5d4af9..f1d3af83 100644
--- a/src/css/modules/code.css
+++ b/src/css/modules/code.css
@@ -71,3 +71,12 @@ html #layuicss-skincodecss{display: none; position: absolute; width: 1989px;}
.layui-code-view.layui-code-hl > .layui-code-ln-side{background-color: transparent;}
.layui-code-theme-dark.layui-code-hl,
.layui-code-theme-dark.layui-code-hl > .layui-code-ln-side{border-color: rgb(126 122 122 / 15%);}
+
+/*行高亮*/
+.layui-code-line-highlighted{background-color:rgba(142, 150, 170, .14)}
+.layui-code-line-diff-add{background-color: rgba(16, 185, 129, .14);}
+.layui-code-line-diff-remove{background-color: rgba(244, 63, 94, .14);}
+.layui-code-line-diff-add:before{position:absolute; content: "+"; color: #18794e;}
+.layui-code-line-diff-remove:before{position:absolute; content: "-"; color: #b8272c;}
+.layui-code-has-focused-lines .layui-code-line:not(.layui-code-line-has-focus) {filter: blur(.095rem); opacity: .7; -webkit-transition: filter .35s, opacity .35s; transition: filter .35s, opacity .35s;}
+.layui-code-has-focused-lines:hover .layui-code-line:not(.layui-code-line-has-focus) {filter: blur(); opacity: 1;}
diff --git a/src/modules/code.js b/src/modules/code.js
index cd4aa7fe..582cf7c2 100644
--- a/src/modules/code.js
+++ b/src/modules/code.js
@@ -48,6 +48,30 @@ layui.define(['lay', 'i18n', 'util', 'element', 'tabs', 'form'], function(export
lang: 'text', // 指定语言类型
highlighter: false, // 是否开启语法高亮,'hljs','prism','shiki'
langMarker: false, // 代码区域是否显示语言类型标记
+ highlightLine: { // 行高亮
+ // 聚焦
+ focus: {
+ range: '', // 高亮范围,不可全局设置值 '1,3-5,8'
+ comment: false, // 是否解析注释,性能敏感不可全局开启 [!code type:]
+ classActiveLine: 'layui-code-line-has-focus', // 添加到高亮行上的类
+ classActivePre: 'layui-code-has-focused-lines' // 有高亮行时向根元素添加的类
+ },
+ // 高亮
+ hl: {
+ comment: false,
+ classActiveLine: 'layui-code-line-highlighted',
+ },
+ // diff++
+ '++':{
+ comment: false,
+ classActiveLine: 'layui-code-line-diff-add',
+ },
+ // diff--
+ '--': {
+ comment: false,
+ classActiveLine: 'layui-code-line-diff-remove',
+ }
+ }
};
// 初始索引
@@ -61,6 +85,91 @@ layui.define(['lay', 'i18n', 'util', 'element', 'tabs', 'form'], function(export
var trim = function(str){
return trimEnd(str).replace(/^\n|\n$/, '');
};
+
+ // '1,3-5,8' -> [1,3,4,5,8]
+ var parseHighlightedLines = function(rangeStr){
+ if (typeof rangeStr !== 'string') return [];
+ var lines = $.map(rangeStr.split(','), function(v){
+ var range = v.split('-');
+ var start = parseInt(range[0], 10);
+ var end = parseInt(range[1], 10);
+ return start && end
+ ? $.map(new Array(end - start + 1), function(_, index){ return start + index })
+ : start ? start : undefined
+ })
+ return lines;
+ }
+
+ // 引用自 https://github.com/innocenzi/shiki-processor/blob/efa20624be415c866cc8e350d1ada886b6b5cd52/src/utils/create-range-processor.ts#L7
+ // 添加了 HTML 注释支持,用来处理预览场景
+ var highlightLineRegex = /(?:\/\/|\/\*{1,2}||-->)?/;
+ var preprocessHighlightLine = function (highlightLineOptions, codeLines) {
+ var hasHighlightLine = false;
+ var needParseComment = false;
+ var lineClassMap = Object.create(null);
+ var preClassMap = Object.create(null);
+
+ var updateLineClassMap = function (lineNumber, className) {
+ if (!lineClassMap[lineNumber]) {
+ lineClassMap[lineNumber] = [CONST.ELEM_LINE];
+ }
+ lineClassMap[lineNumber].push(className);
+ }
+
+ // 收集高亮行 className
+ $.each(highlightLineOptions, function (type, opts) {
+ if (opts.range) {
+ var highlightLines = parseHighlightedLines(opts.range);
+ if (highlightLines.length > 0) {
+ hasHighlightLine = true;
+ if (opts.classActivePre) {
+ preClassMap[opts.classActivePre] = true;
+ }
+ $.each(highlightLines, function (i, lineNumber) {
+ updateLineClassMap(lineNumber, opts.classActiveLine);
+ });
+ }
+ }
+ if (opts.comment) {
+ needParseComment = true;
+ }
+ });
+
+ // 解析行高亮注释并收集 className
+ if (needParseComment) {
+ $.each(codeLines, function (i, line) {
+ var match = line.match(highlightLineRegex);
+ if (match && match[1] && lay.hasOwn(highlightLineOptions, match[1])) {
+ var opts = highlightLineOptions[match[1]];
+ hasHighlightLine = true;
+ if (opts.classActivePre) {
+ preClassMap[opts.classActivePre] = true;
+ }
+ // 高亮的行数
+ var lines = parseInt(match[2], 10)
+ if (match[2] && lines && lines > 1) {
+ var startLine = i + 1;
+ var endLine = startLine + lines - 1;
+ var highlightLines = parseHighlightedLines(startLine + '-' + endLine);
+ if (highlightLines.length > 0) {
+ $.each(highlightLines, function (i, lineNumber) {
+ updateLineClassMap(lineNumber, opts.classActiveLine);
+ });
+ }
+ }else{
+ updateLineClassMap(i + 1, opts.classActiveLine);
+ }
+ }
+ });
+ }
+
+ return {
+ needParseComment: needParseComment,
+ hasHighlightLine: hasHighlightLine,
+ preClass: Object.keys(preClassMap).join(' '),
+ lineClassMap: lineClassMap
+ }
+ }
// export api
exports('code', function(options, mode){
@@ -142,10 +251,16 @@ layui.define(['lay', 'i18n', 'util', 'element', 'tabs', 'form'], function(export
// code 行
var lines = String(html).split(/\r?\n/g);
+ // 预处理行高亮
+ var highlightLineInfo = preprocessHighlightLine(options.highlightLine, lines);
+
// 包裹 code 行结构
html = $.map(lines, function(line, num) {
+ var lineClass = (highlightLineInfo.hasHighlightLine && highlightLineInfo.lineClassMap[num + 1])
+ ? highlightLineInfo.lineClassMap[num + 1].join(' ')
+ : CONST.ELEM_LINE;
return [
- '',
+ '
',
(
options.ln ? [
'
',
@@ -154,12 +269,16 @@ layui.define(['lay', 'i18n', 'util', 'element', 'tabs', 'form'], function(export
].join('') : ''
),
'
',
- (line || ' '),
+ (highlightLineInfo.needParseComment ? line.replace(highlightLineRegex, '') : line) || ' ',
'
',
'
'
].join('');
});
+ if(highlightLineInfo.preClass){
+ othis.addClass(highlightLineInfo.preClass)
+ }
+
return {
lines: lines,
html: html
From 21a25629dd0c2dd84cfa701fdeb78941a9537666 Mon Sep 17 00:00:00 2001
From: morning-star <26325820+Sight-wcg@users.noreply.github.com>
Date: Mon, 8 Sep 2025 23:04:59 +0800
Subject: [PATCH 2/4] =?UTF-8?q?refactor(slider):=20=E4=BD=BF=E7=94=A8=20co?=
=?UTF-8?q?mponent=20=E9=87=8D=E6=9E=84=20slider=20(#2781)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* refactor(slider): 使用 component 重构 slider
* docs(slider): 添加 component 通用接口说明
---------
Co-authored-by: 贤心 <3277200+sentsim@users.noreply.github.com>
---
docs/slider/index.md | 13 +-
src/modules/slider.js | 521 +++++++++++++++++++-----------------------
2 files changed, 239 insertions(+), 295 deletions(-)
diff --git a/docs/slider/index.md b/docs/slider/index.md
index 061098fb..42e102e6 100644
--- a/docs/slider/index.md
+++ b/docs/slider/index.md
@@ -2,7 +2,7 @@
title: 滑块组件 slider
toc: true
---
-
+
# 滑块组件
> 滑块组件 `slider` 是一个拖拽选值的交互性组件,常与 `form` 元素结合使用。
@@ -22,6 +22,7 @@ toc: true
| API | 描述 |
| --- | --- |
| var slider = layui.slider | 获得 `slider` 模块。 |
+| [基础接口](../component/#export)
2.12+ | 该组件由 `component` 构建,因此继承其提供的基础接口。|
| [var inst = slider.render(options)](#render) | slider 组件渲染,核心方法。 |
| [inst.setValue(value)](#setValue) | 设置滑块值 |
| inst.config | 获得当前实例的属性选项 |
@@ -37,7 +38,7 @@ toc: true
-
+